脚本宝典收集整理的这篇文章主要介绍了动态代理(设计模式),脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
代理模式概述
代理模式属于结构型模式,指的是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式包含角色及其职责:
代理模式包含角色及其职责:
设计原则:
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到桥梁的作用, 其特征是代理类与委托类有同样的接口。
代理类不仅仅是一个隔离客户端和委托类的中介。我们还可以借助代理来在增加一些功能,而不需要修改原有代码,严重的符合开闭原则。
代理模式的优点:
源码演示:
第一个:jdk动态代理
1、定义接口类
package com.northeasttycoon.PRoxy.dynamic.proxy; /** * @author :tycoon * @date :2018-10-01 9:08 */ public interface IUserDAO { void findUserPojo(); }
2、实现接口类
package com.northeasttycoon.proxy.dynamic.proxy; /** * @author :tycoon * @date :2018-10-01 9:08 */ public class UserImpl implements IUserDao { @override public void findUserPojo() { System.out.println("此方法为jdk动态代理。查询用户信息为:{userID:1001,userName:Northeast Tycoon,alias:Java.Zhao}"); } }
3、jdk动态代理实现类
package com.northeasttycoon.proxy.dynamic.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author :tycoon * @date :2018-10-01 9:07 */ public class ProxyInvocationHandler implements InvocationHandler { // 需要代理的对象,既:真实对象 private Object target; public void setObject(Object target) { this.target = target; } public Object getProxy() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /* * 处理代理对象的方法时会调用此方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); // 通过反射实现动态代理,调用真实对象方法 Object result = method.invoke(target, args); after(); return result; } // 执行前-增强方法 public void before() { System.out.println(" This is northeasttycoon jdkDynamicProxy,调用动态代理方法前------"); } // 执行后-增强方法 public void after() { System.out.println("This is northeasttycoon jdkDynamicProxy,调用动态代理方法后------"); } }
第二个:cglib 动态代理
1、定义目标对象(真实对象)
package com.northeasttycoon.proxy.dynamic.proxy; /** * @author :tycoon * @date :2018-10-01 9:10 */ public class UserDao { public void findUserPojo() { System.out.println("此方法为CGlib动态代理。查询用户信息为:{userID:1001,userName:Northeast Tycoon,alias:Java.Zhao}"); } }
2、cglib 动态代理类
package com.northeasttycoon.proxy.dynamic.proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @author :tycoon * @date :2018-10-01 9:28 */ public class CglibDynamicProxy implements MethodInterceptor { //维护一个目标对象 private Object target; //构造器,传入一个被代理的对象 public CglibDynamicProxy(Object target) { this.target = target; } //返回一个代理对象: 是 target 对象的代理对象 public Object getProxyInstance() { //1. 通过CGLIB动态代理获取代理对象的过程 Enhancer enhancer = new Enhancer(); //2. 设置enhancer对象的父类 enhancer.setSuPErclass(target.getClass()); //3. 设置enhancer的回调对象 enhancer.setCallback(this); //4. 创建子类对象,即代理对象 return enhancer.create(); } /** * 重写 intercept 方法,会调用目标对象的方法 * @param arg0 cglib生成的代理对象 * @param method 被代理对象的方法 * @param args 传入方法的参数 * @param arg3 代理的方法 * @return 对象 * @throws Throwable */ @Override public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable { System.out.println("cglib代理模式 ~~ start"); Object returnVal = method.invoke(target, args); System.out.println("cglib代理模式 ~~ end"); return returnVal; } }
测试类
package com.northeasttycoon.proxy.dynamic.proxy; import org.junIT.jupiter.api.test; /** * @author :tycoon * @date :2018-10-01 9:18 */ public class TestProxy { /** * jdk 动态代理实现 */ @Test public void test01(){ //需要被代理的对象 UserImpl userService = new UserImpl(); //生成代理类 ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setObject(userService); IUserDao proxy = (IUserDao) pih.getProxy(); //调用代理类的方法 proxy.findUserPojo(); } /** * cglib的动态代理 */ @Test public void test02(){ //创建目标对象 UserDao target = new UserDao(); //获取到代理对象,并且将目标对象传递给代理对象 UserDao proxyInstance = (UserDao)new CglibDynamicProxy(target).getProxyInstance(); //执行代理对象的方法,触发intecept 方法,实现对目标对象的调用 proxyInstance.findUserPojo(); } }
测试结果:
以上是脚本宝典为你收集整理的动态代理(设计模式)全部内容,希望文章能够帮你解决动态代理(设计模式)所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。