動態(tài)代理

動態(tài)代理的實現(xiàn)有兩種方式:1. jdk動態(tài)代理;2. cglib動態(tài)代理

jdk動態(tài)代理

使用反射包中的類和接口實現(xiàn)動態(tài)代理的功能,反射包java.lang.reflect,里面有三個類:InvocationHandler,MethodProxy

InvocationHandler接口:invoke(),表示代理類中要執(zhí)行的功能代碼。代理類的功能要寫在invoke()方法中。

/**
 * param proxy  動態(tài)代理創(chuàng)建出的對象
 * param method 目標(biāo)方法
 * param args 目標(biāo)參數(shù)
 */
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

Proxy核心的對象。用來創(chuàng)建動態(tài)代理的對象。之前創(chuàng)建的對象都是new類的構(gòu)造方法(),動態(tài)代理中使用Proxy類中的方法來代替new。

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
動態(tài)代理的兩個示例
  1. 動態(tài)生成實現(xiàn)了UserMapper接口的類
public interface UserMapper {

    /**
     * 通過用戶ID查詢用戶名
     */
    String getUsernameByUserId(Long id);

    /**
     * 通過用戶名查詢用戶數(shù)量
     */
    Long countByUsername(String username);
}

實現(xiàn)InvocationHandler并且創(chuàng)建出代理類:

/**
 * @author YanYu
 */
public class MapperHandler implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("getUsernameByUserId".equals(method.getName())) {
            System.out.println("通過用戶ID查詢用戶名");
            return "admin " + "id:" + args[0];
        } else if ("countByUsername".equals(method.getName())) {
            System.out.println("通過用戶名查詢用戶數(shù)量,username: " + args[0]);
            return 1L;
        }
        throw new RuntimeException("method not found");
    }

    public static void main(String[] args) {
        UserMapper userMapper = (UserMapper) Proxy.newProxyInstance(
                MapperHandler.class.getClassLoader(),
                new Class[]{ UserMapper.class },
                new MapperHandler()
        );
        System.out.println(userMapper.getUsernameByUserId(5L));
        System.out.println(userMapper.countByUsername("admin"));
    }
}
  1. 使用動態(tài)代理對UserServiceImpl類進(jìn)行增強(qiáng):
public interface UserService {
    String findUsernameByUserId(Long userId);
}
public class UserServiceImpl implements UserService {

    @Override
    public String findUsernameByUserId(Long userId) {
        System.out.println("從數(shù)據(jù)庫中查詢userId: " + userId + " 的用戶");
        return "admin";
    }
}
public class ServiceHandler implements InvocationHandler {

    private Object target;

    public ServiceHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("開啟數(shù)據(jù)庫連接。。。。");
        Object result = method.invoke(target, args);
        System.out.println("關(guān)閉數(shù)據(jù)庫連接。。。。");
        return result;
    }

    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(
                userService.getClass().getClassLoader(),
                UserServiceImpl.class.getInterfaces(),
                new ServiceHandler(userService)
        );
        System.out.println(userServiceProxy.findUsernameByUserId(5L));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容