动态代理

动态代理的实现有两种方式:1. jdk动态代理;2. cglib动态代理

jdk动态代理

使用反射包中的类和接口实现动态代理的功能,反射包java.lang.reflect,里面有三个类:InvocationHandlerMethodProxy

InvocationHandler接口:invoke(),表示代理类中要执行的功能代码。代理类的功能要写在invoke()方法中。

/**
 * param proxy  动态代理创建出的对象
 * param method 目标方法
 * param args 目标参数
 */
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

Proxy核心的对象。用来创建动态代理的对象。之前创建的对象都是new类的构造方法(),动态代理中使用Proxy类中的方法来代替new。

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
动态代理的两个示例
  1. 动态生成实现了UserMapper接口的类
public interface UserMapper {

    /**
     * 通过用户ID查询用户名
     */
    String getUsernameByUserId(Long id);

    /**
     * 通过用户名查询用户数量
     */
    Long countByUsername(String username);
}

实现InvocationHandler并且创建出代理类:

/**
 * @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("通过用户名查询用户数量,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. 使用动态代理对UserServiceImpl类进行增强:
public interface UserService {
    String findUsernameByUserId(Long userId);
}
public class UserServiceImpl implements UserService {

    @Override
    public String findUsernameByUserId(Long userId) {
        System.out.println("从数据库中查询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("开启数据库连接。。。。");
        Object result = method.invoke(target, args);
        System.out.println("关闭数据库连接。。。。");
        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));
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容