美文网首页
Java动态代理实例简介

Java动态代理实例简介

作者: 大鹏_xzlp | 来源:发表于2017-10-07 11:42 被阅读0次

    1.Proxy动态代理

    我们先来看一下普通的工厂方法下的实现:

    public interface UserService {
        public void save();
        public void delete();
        public void update();
        public void query();
    }
    
    public class UserServiceImpl implements UserService{
        public void save() {
            System.out.println("save");
        }
    
        public void delete() {
            System.out.println("delete");
        }
    
        public void update() {
            System.out.println("update");
        }
    
        public void query() {
            System.out.println("query");
        }
    }
    
    public class UserServiceProxyFactory {
        public UserServiceProxyFactory() {
        }
        public UserService getUserService(){
            return new UserServiceImpl();
        }
    }
    
    UserServiceProxyFactory factory = new UserServiceProxyFactory();
    UserService userService = factory.getUserService();
    userService.save();
    userService.query();
    

    打印了:

    save
    query
    
    

    假如此时我们需要在UserService的四个方法都加上事务判断,那么需要在每个方法里面加上一段代码,显然是不好的,这时我们使用动态代理来看一下怎么做.

    我们让工厂以动态代理的方式来实现:

    public class UserServiceProxyFactory implements InvocationHandler{
        private UserService userService;
    
        public UserServiceProxyFactory(UserService userService) {
            this.userService = userService;
        }
    
        public UserService getUserServiceProxy(){
            //生成动态代理
            return (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                    UserServiceImpl.class.getInterfaces(),this);
    
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("打开事务");
            Object invoke = method.invoke(userService,args);
            System.out.println("关闭事务");
            return invoke;
        }
    }
    
    UserService us = new UserServiceImpl();
    UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
    UserService userService = factory.getUserServiceProxy();
    userService.save();
    userService.query();
    
    打开事务
    save
    关闭事务
    打开事务
    query
    关闭事务
    

    可以看到使用了动态代理后每个方法前后都加入了事务管理,我们再来看一下UserService userService = factory.getUserServiceProxy();返回的是什么

    System.out.println(userService instanceof UserServiceImpl);
    System.out.println(userService.getClass());
    
    false
    class com.sun.proxy.$Proxy0
    
    

    可以看出来这个并不是我们的UserServiceImpl对象,而是一个代理类,它同样实现了UserService接口,如果我们要代理的类没有实现某个接口的话不能使用这种方法,要用cglib动态代理

    2.cglib动态代理

    public class UserServiceProxyFactory2 implements MethodInterceptor{
    
        public UserServiceImpl getUserServiceProxy(){
            Enhancer en = new Enhancer();//生成代理对象
            en.setSuperclass(UserServiceImpl.class);//对谁代理
            en.setCallback(this);
            UserServiceImpl userService = (UserServiceImpl) en.create();
            return userService;
        }
    
        /** 
         * @param obj 代理对象 
         * @param method 调用的方法,基于jdk reflect,此方法不能直接在当前对象中使用,只能使用在其他实例上,否则将无限循环触发"拦截器" 
         * @param proxy 经过封装的代理类的方法 
         */  
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("打开事务");
            Object value =   proxy.invokeSuper(obj, args);//这里要特别注意使用的是invokeSuper方法
            System.out.println("关闭事务");
            
             //如下两个方法,不能在当前代理对象中使用.  
            //method.invoke(other, args);  
            //proxy.invoke(other, args);  
            return value;
        }
    }
    
    UserServiceProxyFactory2 factory2 = new UserServiceProxyFactory2();
    UserServiceImpl userService = factory2.getUserServiceProxy();
    userService.save();
    userService.query();
    
    打开事务
    save
    关闭事务
    打开事务
    query
    关闭事务
    
     System.out.println(userService instanceof UserServiceImpl);
    System.out.println(userService.getClass());
    
    true
    class com.test.service.UserServiceImpl$$EnhancerByCGLIB$$e0e91299
    

    可以看出使用这种方式拿到的代理是继承了UserServiceImpl

    相关文章

      网友评论

          本文标题:Java动态代理实例简介

          本文链接:https://www.haomeiwen.com/subject/wnqjyxtx.html