# Java高级之使用反射实现动态代理 **Repository Path**: fpfgitmy_admin/java-high-class-porxy ## Basic Information - **Project Name**: Java高级之使用反射实现动态代理 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-04-28 - **Last Updated**: 2021-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 反射的应用:动态代理 + 使用一个代理将对象包装起来,然后该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上 + 静态代理:特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理 + 动态代理是指客户通过代理类来调用其他对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象 + 动态代理使用场合: + 调式 + 远程方法调用 + 动态代理相比于静态代理的优点: + 抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和同意的处理众多的方法 #### 静态代理案例 ``` package com.felixfei.study.test; /** * @describle 静态代理举例 * 特点:代理类和被代理类在编译期间,就确定下来了 */ interface ClothFactory { void produceCloth(); } // 代理类 class ProxyClothFactory implements ClothFactory { private ClothFactory factory; public ProxyClothFactory(ClothFactory factory) { this.factory = factory; } @Override public void produceCloth() { System.out.println("代理工厂做一些准备工作"); factory.produceCloth(); System.out.println("代理工厂做一些后续的收尾工作"); } } // 被代理类 class NikeClothFactory implements ClothFactory { @Override public void produceCloth() { System.out.println("Nike工厂生产运动服"); } } public class StaticProxyTest { public static void main(String[] args) { // 创建被代理类对象 NikeClothFactory nike = new NikeClothFactory(); // 创建代理类对象 ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike); proxyClothFactory.produceCloth(); } } ``` #### 动态代理的案例 ``` package com.felixfei.study.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @describle 动态代理的举例 */ interface Human { String getBelief(); void eat(String food); } // 被代理类 class SuperMan implements Human { @Override public String getBelief() { return "I believe I can fly!"; } @Override public void eat(String food) { System.out.println("我喜欢吃" + food); } } /** * 要想实现动态代理:需要解决的问题? * 问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象 * 问题二:当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法 */ class ProxyFactory { // 调用此方法,返回一个代理类的对象。解决问题一 public static Object getProxyInstance(Object obj) {// obj:被代理类的对象 MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); myInvocationHandler.bind(obj); // 第二个参数的意思:因为被代理类和代理类要实现同样的接口 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler); } } class MyInvocationHandler implements InvocationHandler { // 赋值时,需要使用被代理类的对象进行赋值 private Object obj; public void bind(Object obj) { this.obj = obj; } // 当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法,invoke() // 将被代理类要执行的方法a的功能就声明在invoke()中 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法 // obj:被代理类的对象 Object value = method.invoke(obj, args); // 上述方法的返回值 return value; } } public class ProxyTest { public static void main(String[] args) { SuperMan superMan = new SuperMan(); // 代理类的对象 Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan); // 当通过代理类对象调用方法时,会自动的调用被代理类中的同名方法 String belief = proxyInstance.getBelief(); System.out.println(belief); proxyInstance.eat("果子"); System.out.println("*********************"); // 动态?:代理类动态 // 只需要提供代理类,就能代理被代理类 NikeClothFactory nikeClothFactory = new NikeClothFactory(); ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory); proxyInstance1.produceCloth(); } } ```