时间:2021-05-19
什么是代理?
为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间
什么是静态代理?
由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在
通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的。
优点
缺点
案例演示
PayService.java(接口)
package net.cybclass.sp.proxy;public interface PayService { /** * 支付回调 * @param outTradeNo 订单号 * @return */ String callback(String outTradeNo); /** * 下单 * @param userId 用户id * @param productId 产品id * @return */ int save(int userId,int productId);}PayServiceImpl.java(接口实现类)
package net.cybclass.sp.proxy;public class PayServiceImpl implements PayService{ public String callback(String outTradeNo) { System.out.println("目标类 PayServiceImpl 回调 方法 callback"); return outTradeNo; } public int save(int userId, int productId) { System.out.println("目标类 PayServiceImpl 回调 方法 save"); return productId; }}StaticProxyPayServiceImpl.java(接口实现类,静态代理)
package net.cybclass.sp.proxy;public class StaticProxyPayServiceImpl implements PayService{ private PayService payService; public StaticProxyPayServiceImpl(PayService payService) { this.payService=payService; } public String callback(String outTradeNo) { System.out.println("StaticProxyPayServiceImpl callback begin"); String result=payService.callback(outTradeNo); System.out.println("StaticProxyPayServiceImpl callback end"); return result; } public int save(int userId, int productId) { System.out.println("StaticProxyPayServiceImpl save begin"); int id = payService.save(userId, productId); System.out.println("StaticProxyPayServiceImpl save end"); return id; }}演示
什么是动态代理?
在程序运行时,运用反射机制动态创建而成,无需手动编写代码
JDK动态代理
CGLIB动态代理(原理:是对指定的业务类生成一个子类,并覆盖其中的业务方法来实现代理)
jdk动态代理演示
定义一个类,去实现InvocationHandler这个接口,并车从写invoke方法//Object proxy:被代理的对象//Method method:要调用的方法//Object[] args:方法调用时所需要参数public Object invoke(Object proxy, Method method, Object[] args){}PayService.java(接口)
package net.cybclass.sp.proxy;public interface PayService { /** * 支付回调 * @param outTradeNo 订单号 * @return */ String callback(String outTradeNo); /** * 下单 * @param userId 用户id * @param productId 产品id * @return */ int save(int userId,int productId);}PayServiceImpl.java(接口实现类)
package net.cybclass.sp.proxy;public class PayServiceImpl implements PayService{ public String callback(String outTradeNo) { System.out.println("目标类 PayServiceImpl 回调 方法 callback"); return outTradeNo; } public int save(int userId, int productId) { System.out.println("目标类 PayServiceImpl 回调 方法 save"); return productId; }}JDKProxy.java(jdk动态代理类)
package net.cybclass.sp.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class JDKProxy implements InvocationHandler { //目标类 private Object targetObject; /** * 获取代理对象 * @param targetObject 目标类 * @return */ public Object newProxyInstance(Object targetObject) { this.targetObject = targetObject; //绑定关系,也就是和具体的那个实现类关联 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } /** * JDK动态代理 * * @param proxy 静态代理对象 * @param method 要调用的方法 * @param args 方法调用时所需要参数 * @return * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { System.out.println("通过JDK动态代理调用"+method.getName()+",打印日志 begin"); result = method.invoke(targetObject, args); System.out.println("通过JDK动态代理调用"+method.getName()+",打印日志 end"); } catch (Exception ex) { ex.printStackTrace(); } return result; }}CGLIB动态代理演示
PayService.java(接口)
package net.cybclass.sp.proxy;public interface PayService { /** * 支付回调 * @param outTradeNo 订单号 * @return */ String callback(String outTradeNo); /** * 下单 * @param userId 用户id * @param productId 产品id * @return */ int save(int userId,int productId);}PayServiceImpl.java(接口实现类)
package net.cybclass.sp.proxy;public class PayServiceImpl implements PayService{ public String callback(String outTradeNo) { System.out.println("目标类 PayServiceImpl 回调 方法 callback"); return outTradeNo; } public int save(int userId, int productId) { System.out.println("目标类 PayServiceImpl 回调 方法 save"); return productId; }}CGLIBProxy.java(CGLIB动态代理类)
package net.cybclass.sp.proxy;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CGLIBProxy implements MethodInterceptor { //目标类 private Object targetObject; //绑定关系 public Object newProxyInstance(Object targetObject){ this.targetObject=targetObject; Enhancer enhancer=new Enhancer(); //设置代理类的父类(目标类) enhancer.setSuperclass(this.targetObject.getClass()); //设置回调函数 enhancer.setCallback(this); //创建子类(代理对象) return enhancer.create(); } public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object result=null; try { System.out.println("通过CGLIB动态代理调用"+method.getName()+",打印日志 begin"); result=methodProxy.invokeSuper(o,args); System.out.println("通过CGLIB动态代理调用"+method.getName()+",打印日志 end"); } catch (Exception ex){ ex.printStackTrace(); } return result; }}总结
动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理,解耦和易维护。
两种动态代理的区别
Spring AOP中的代理使用的默认策略
到此这篇关于 Spring AOP里的静态代理和动态代理用法详解的文章就介绍到这了,更多相关 Spring AOP 静态代理 动态代理内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
详解Java动态代理的实现及应用Java动态代理其实写日常业务代码是不常用的,但在框架层一起RPC框架的客户端是非常常见及重要的。spring的核心思想aop的
Java反射机制与动态代理,使得Java更加强大,Spring核心概念IoC、AOP就是通过反射机制与动态代理实现的。1Java反射示例:Useruser=ne
AOP面向切面编程(AspectOrientedProgramming),是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。Spring框架
正文关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理。静态代理1、
@Transactional内部调用例子🌰在Spring的AOP代理下,只有目标方法由外部调用,目标方法才由Spring生成的代理对象来管理,这