• java动态代理 和cglib


    理解:动态代理主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法

      代理对象与被代理对象继承相同的接口,他们并没有继承关系

    模拟javaEE的service层

    1、定义接口

    UserService.java

    public interface UserService {
        public void save();
        public void delete();
        public void update();
        public void find();
    }

    2、定义实现类

    UserServiceImpl.java

    public class UserServiceImpl implements UserService {
    
        public void save() {
            System.out.println("保存");
        }
    
        public void delete() {
            System.out.println("删除");
        }
    
        public void update() {
            System.out.println("更新");
        }
    
        public void find() {
            System.out.println("查找");
        }
    }

    3、增强类(动态代理)

    UserServiceProxyFactory.java

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class UserServiceProxyFactory implements InvocationHandler {
    
        //要增强的对象
        private UserService us;
        
        public UserServiceProxyFactory(UserService us){
            this.us = us;
        }
        
        public UserService getUserServiceProxy(){
            //生成动态代理
            //动态代理参数一:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
            //参数二:被代理对象的接口,(一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了)
            //参数三:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上(因为继承了InvocationHandler所以参数三可以传this)
            UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                    UserServiceImpl.class.getInterfaces(),
                    this);
            return usProxy;
        }
    
        
        //增强方法
        //proxy:指代我们所代理的那个真实对象
        //method:指代的是我们所要调用真实对象的某个方法的Method对象
        //args:指代的是调用真实对象某个方法时接受的参数
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            //调用该方法内容前增强
            System.out.println("打开事务");
            Object invoke = method.invoke(us, args);
            //调用该方法后增强
            System.out.println("关闭事物");
            return invoke;
        }
        
    }

    4、测试类

    Demo.java

    public class Demo {
    
        @Test
        public void testProxy(){
            UserService us = new UserServiceImpl();
            UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
            UserService usProxy = factory.getUserServiceProxy();
        //代理对象与被代理对象实现了相同的接口
        //代理对象 与 被代理对象没有继承关系
            usProxy.save();
        }
        
    }

    5、增强类(cglib代理)

    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import cn.itcast.service.UserService;
    import cn.itcast.service.UserServiceImpl;
    
    //cglib代理
    public class UserServiceProxyFactory2 implements MethodInterceptor {
        
    
        public UserService getUserServiceProxy(){
            
            Enhancer en = new Enhancer();//帮我们生成代理对象
            
            en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
            
            en.setCallback(this);//代理要做什么
            
            UserService us = (UserService) en.create();//创建代理对象
            
            return us;
        }
    
        @Override
        public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
            //打开事务
            System.out.println("打开事务!");
            //调用原有方法
            Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
            //提交事务
            System.out.println("提交事务!");
            
            return returnValue;
        }
    
    
    }

    6、测试类

    public class Demo {
        
        @Test
        public void fun2(){
            
            UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
            
            UserService usProxy = factory.getUserServiceProxy();
            
            usProxy.save();
            
            //判断代理对象是否属于被代理对象类型
            //代理对象继承了被代理对象=>true
            System.out.println(usProxy instanceof UserServiceImpl );//true
        }
    }

    总结:java动态代理:所代理对象与被代理对象继承相同的接口,他们并没有继承关系,cglib代理:代理对象继承了被代理对象(如果目标对象被final修饰,那么该类无法使用cglib代理)

       java动态代理:需要被代理的类有实现某个接口,cglib代理:可以代理一般类,不需要被代理类实现任何接口

  • 相关阅读:
    c++调用lua
    HTTP实现长连接(TTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持Connection: keep-alive)
    C++: std::string 与 Unicode 如何结合?
    统计一下你写过多少代码
    解读jQuery中extend函数
    C#如何通过SOCKET的方式获取HTTPONLY COOKIE
    Java进阶代码
    SQLSERVER聚集索引与非聚集索引的再次研究(上)
    c,c++函数返回多个值的方法
    COM思想的背后
  • 原文地址:https://www.cnblogs.com/ms-grf/p/7423439.html
Copyright © 2020-2023  润新知