静态代理与Jdk动态代理

1、静态代理

    /**抽象对象:声明了真实对象和代理对象的公共方法(男性情趣用品公司接口)*/
    public interface Subject {
        void saleTt();
    }
    /**真实对象:代理对象所代表的真实对象,最终被引用的对象(A情趣用品公司)*/
    public class RealSubject implements Subject {
        public void saleTt() {
            //....真实对象的处理方法
        }
    }
    /**代理对象:包含真实对象从而操作真实主题对象,相当于访问者和真实对象直接的中介(个人代购)*/
    public class Proxy implements Subject {
        private Subject subject;
        public Proxy(Subject subject) {
            this.subject = subject;
        }
        public void saleTt() {
            doBefore();//前置增强
            subject.saleTt();//真实对象的业务处理
            doAfter();//后置增强
        }
    }
    /**访问者:通过代理对象访问目标对象的方法(张三)*/
    public class Client {
        public static void main(String[] args) {
            Subject subject = new RealSubject();
            Proxy proxy = new Proxy(subject);
            proxy.saleTt();
        }
    }

静态代理使用代理类中的入参为真实对象的构造方法生成代理类,通过代理类的方法 去调用真实对象的方法;与特定的真实对象耦合,如果有新的需求,需要修改代理类 来实现。

  • 不足之处: 扩展性差,可维护性差;

2、动态代理

    /**抽象对象:声明了真实对象和代理对象的公共接口(公司接口)*/
    public interface ManToolsCompany {
        void saleManTool(String size);
    }
    /**真实对象:代理对象所代表的真实对象,最终被引用的对象(A公司,B公司)*/
    public class AaCompany implements ManToolsCompany {
        @Override
        public void saleManTool(String size) {
            //...真实对象的业务处理
        }
    }
    /**代理对象:包含真实对象从而操作真实主题对象,相当于访问者和真实对象直接的中介(海外代购公司)*/
    public class LisonCompany implements InvocationHandler {
        //代理对象
        private Object compy;
        /**标注服务流程*/
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            doSomeThingBefore();//前置增强
            Object invoke = method.invoke(compy, args);//反射调用代购公司业务处理方法
            doSomeThingEnd();//后置增强
            return invoke;
        }
        //获取代理示例
        public Object getProxyInstance(){
            return Proxy.newProxyInstance(compy.getClass().getClassLoader(), compy.getClass().getInterfaces(), this);
        }
    }
    /**访问者:通过代理对象访问目标对象的方法(张三,张三媳妇)*/
    public class Client {
        public static void main(String[] args) {
            //真实对象
            ManToolsCompany aacomp = new AaCompany();
            WomanToolsCompany bbcomp = new BbCompany();
            //代理对象
            LisonCompany lisonCompany = new LisonCompany();

            lisonCompany.setCompy(aacomp);
            ManToolsCompany lison1 = (ManToolsCompany) lisonCompany.getProxyInstance();
            lison1.saleManTool("C");

            lisonCompany.setCompy(bbcomp);
            WomanToolsCompany lison2 = (WomanToolsCompany) lisonCompany.getProxyInstance();
            lison2.saleWomanTool(1.8f);

            ProxyUtils.generateClassFile(ManToolsCompany.class, lison1.getClass().getName());
            ProxyUtils.generateClassFile(WomanToolsCompany.class, lison2.getClass().getName());
        }
    }

动态代理的代理类实现特定InvocationHandler接口, 在类中使用Object类型的变量, 任何真实对象都可以传入,使用Proxy的静态方法newProxyInstance方法根据 传入Object类的类的相关信息(类加载器、实现的接口、当前对象)来生成真实对象的实例, 重写invoke方法,在invoke方法中调用真实对象的业务方法,在调用方法前后进行增强处理。 在通过代理类生成的真实对象的方法被调用时,调用了代理类中的重写的invoke方法,实现功能。

  • 动态代理的优点: 不与特定的真实对象耦合,业务修改只需要增加新的真实对象,代理类不用修改。

JDK动态代理

Proxy:有资源的海外代购人(全职、兼职),调度中心,使用静态方法Proxy.newProxyInstance生成真实对象
InvocationHandler:优质的代购服务,提供标准服务,在invoke方法之前之后可以进行增强

类的完整生命周期

Java源文件(Java文件)–编译–>Java字节码(.class文件)–类加载–>Class对象–实例化–>实例对象—->卸载

.java源文件通过javac命令编译为.class字节码文件,通过类加载器ClassLoader加载全类名的.class文件在JVM中生成Class对象, 在new的时候通过Class对象实例化出对象实例进行使用,垃圾回收时实例对象的可达性分析与根节点没有关联时jvm卸载对象。

猜你喜欢

转载自blog.csdn.net/u014653854/article/details/81173320