美文网首页
代理模式实战

代理模式实战

作者: 奋斗的韭菜汪 | 来源:发表于2020-06-15 06:34 被阅读0次

    定义:是指对其他对象提供一种代理,以控制对这个对象的访问,代理对象在服务端和目标对象之间起到中介作用
    使用场景:1、保护目标对象, 2、增强目标对象功能
    静态代理举例:

    public class Zhangsan implements IPerson {
        @Override
        public void findLove() {
            System.out.println("肤白貌美大长腿");
        }
    }
    
    public class Zhanglaosan implements IPerson {
        private Zhangsan zhangsan;
        public Zhanglaosan(Zhangsan zhangsan) {
            this.zhangsan = zhangsan;
        }
        @Override
        public void findLove() {
            System.out.println("要孝顺!");
            zhangsan.findLove();
            System.out.println("能生娃");
    
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Zhanglaosan zhanglaosan =new Zhanglaosan(new Zhangsan());
            //通过调用张三他爸这个代理对象实现张三找对象这个事情,同时还能对张三找对象这个问题进行增强
            zhanglaosan.findLove();
        }
    }
    

    jdk动态代理和cglib动态代理的本质区别:
    cglib是代理类直接继承(继承子类就有了父类的方法)目标类的,不需要实现接口(重写接口所有方法);
    jdk目标类实现了接口;
    jdk动态代理需要获取目标类的所有接口作为生产代理对象的参数

    sping源码中会去判断类是否实现接口,若实现接口则使用jdk动态代理,若没有实现接口会使用cglib动态代理,(优先使用jdk动态代理)
    可以手动配置强制使用cglib动态代理模式生产代理对象

    java动态代理

    public interface IPerson {
        void findLove();
        void buy();
    }
    
    public class JdkProxy implements InvocationHandler{
        private IPerson  targer;
        public IPerson getInstance(IPerson targer){
            this.targer = targer;
            Class<? extends IPerson> targerClass = targer.getClass();
            //argerClass.getInterfaces()不关心目标对象实现的接口是什么(随便是人还是动物都可以,比较灵活)
            //静态代理是硬编码(父亲),
            //argerClass.getInterfaces() jdk动态代理目标对象需要实现接口,区别于cglib
            return (IPerson) Proxy.newProxyInstance(targerClass.getClassLoader(), targerClass.getInterfaces(),this);
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            beforeMethod();
            Object result = method.invoke(this.targer, args);
            afterMethod();
            return result;
        }
        private void afterMethod() {
            System.out.println("代理对象后面干点啥");
        }
        private void beforeMethod() {
            System.out.println("代理对象前面干点啥");
        }
    }
    
    public class Lisi implements IPerson {
        @Override
        public void findLove() {
            System.out.println("有才华");
        }
        @Override
        public void buy() {
            System.out.println("买个平安保险");
        }
    }
    
    public class Zhangsan implements IPerson {
        @Override
        public void findLove() {
            System.out.println("肤白貌美大长腿");
        }
        @Override
        public void buy() {
            System.out.println("买个人寿保险");
        }
    }
    
    
    public class Test {
        public static void main(String[] args) {
            JdkProxy jdkProxy = new JdkProxy();
            //左边lisi对象已经不是右边李四对象了,而是一个通过字节码生成的一个代理对象
            IPerson lisi = jdkProxy.getInstance(new Lisi());
            lisi.findLove();
            lisi.buy();
            IPerson zhangsan = jdkProxy.getInstance(new Zhangsan());
            zhangsan.findLove();
            zhangsan.buy();
        }
    }
    

    cglib动态代理

    public class CglibProxy implements MethodInterceptor{
        //cglib是直接继承(继承子类就有了父类的方法)目标类的,不需要实现接口(重写接口所有方法)
        public Object getInstance(Class<?> clazz){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            return enhancer.create();
        }
        private void afterMethod() {
            System.out.println("代理对象后面干点啥");
        }
        private void beforeMethod() {
            System.out.println("代理对象前面干点啥");
        }
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            beforeMethod();
            Object result = methodProxy.invokeSuper(o, objects);
            afterMethod();
            return result;
        }
    }
    
    public class Zhangsan{
        public void findLove() {
            System.out.println("高挑的");
        }
        public void buy() {
            System.out.println("买个cglib保险");
        }
    }
    
    
    public class Test {
        public static void main(String[] args) {
            CglibProxy cglibProxy = new CglibProxy();
            Zhangsan zhangsanProxy = (Zhangsan)cglibProxy.getInstance(Zhangsan.class);
            zhangsanProxy.findLove();
            zhangsanProxy.buy();
        }
    }
    

    相关文章

      网友评论

          本文标题:代理模式实战

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