有一种代理叫动态代理-什么叫动态代理

定义动态代理指的是,代理类和目标类的关系在程序运行的时候确定的,客户通过代理类来调用目标对象的方法,是在程序运行时根据需要动态的创建目标类的代理对象 。
分类

  • jdk动态代理
  • cglib动态代理
案例需求苹果公司通过苹果代理商来卖手机
方案一:jdk动态代理定义抽象接口
/** * 售卖手机的接口(代理模式——抽象角色) * @author:liyajie * @createTime:2022/2/22 14:42 * @version:1.0 */public interface IPhone {/*** 出售手机* @author: liyajie* @date: 2022/2/22 14:44* @param* @return void* @exception:* @update:* @updatePerson:**/void sellPhone();}
定义目标类实现接口,重写接口方法
/** * 苹果公司(代理模式——目标角色) * @author:liyajie * @createTime:2022/2/22 14:46 * @version:1.0 */public class TargetPhone implements IPhone {@Overridepublic void sellPhone() {System.out.println("苹果公司正在出售手机");}}
定义代理类
/** * 代理商(代理模式——代理角色) * @author:liyajie * @createTime:2022/2/22 14:50 * @version:1.0 */public class ProxyPhone {private Object target;public ProxyPhone(Object target){this.target = target;}public Object getProxyInstance() {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK动态代理开始之前,添加业务逻辑XXX");//使用反射机制来调用目标对象的方法:解决了问题二Object invoke = method.invoke(target, args);System.out.println("JDK动态代理结束之后,添加业务逻辑XXX");return invoke;}});}}
定义测试类
/** * 测试类 * @author:liyajie * @createTime:2022/2/23 15:15 * @version:1.0 */public class Test {public static void main(String[] args) {// 创建目标类TargetPhone targetPhone = new TargetPhone();// 创建代理类IPhone iPhone = (IPhone) new ProxyPhone(targetPhone).getProxyInstance();System.out.println(iPhone.getClass());// 通过代理类调用目标方法iPhone.sellPhone();}}
查看测试结果
有一种代理叫动态代理-什么叫动态代理

文章插图
方案二:cglib动态代理定义目标类
/** * 苹果公司(代理模式——目标角色) * @author:liyajie * @createTime:2022/2/22 14:46 * @version:1.0 */public class TargetPhone {public void sellPhone() {System.out.println("苹果公司正在出售手机");}}
定义代理工厂,用来获取代理类
/** * 代理工厂 * @author:liyajie * @createTime:2022/2/23 15:32 * @version:1.0 */public class ProxyFactory implements MethodInterceptor {private Object target;public ProxyFactory(Object target){this.target = target;}public Object getProxyInstance(){// 创建一个工具类Enhancer enhancer = new Enhancer();// 设置父类enhancer.setSuperclass(target.getClass());// 设置回调函数enhancer.setCallback(this);// 创建子类对象,即代理对象return enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("cglib动态代理开始之前,添加业务逻辑xxxx");Object invoke = method.invoke(target, objects);System.out.println("cglib动态代理之后,添加业务逻辑");return invoke;}}
定义测试类
/** * 测试类 * @author:liyajie * @createTime:2022/2/23 15:44 * @version:1.0 */public class Test {public static void main(String[] args) {// 创建目标对象TargetPhone targetPhone = new TargetPhone();// 获取代理对象TargetPhone proxyInstance = (TargetPhone)new ProxyFactory(targetPhone).getProxyInstance();// 通过代理对象调用具体的方法proxyInstance.sellPhone();}}
查看测试结果
有一种代理叫动态代理-什么叫动态代理

文章插图
分析首先可以看到不管是jdk动态代理,还是cglib动态代理,实现的效果和静态代理是一模一样的,都实现了功能的扩展 。但是两种动态代理还是有些不同的,其中jdk动态代理需要目标对象实现接口,但是cglib动态代理不需要,因为他是在内存中构建一个子类对象,从而实现对目标对象的功能扩展 。
总结【有一种代理叫动态代理-什么叫动态代理】通过案例,我们了解了代理模式的几种实现方式,下面我们总结下该模式:
  • 优势:
  1. 代理模式在客户端和目标对象之间起到了一个中介和保护的作用
  2. 代理对象可以对目标对象进行功能的扩展和业务的扩展,增强目标对象
  3. 代理模式可以将客户端和目标对象分离,在一定程度上降低了系统的耦合度