内容简介:本文主要讲的是如何使用JDK中提供了一个该代理对象的实现类实现了interfaces所指定的系列接口,执行代理对象的每个方法时都会被替换执行
本文主要讲的是如何使用 JDK动态代理 实现简单的AOP。AOP是啥?如果你想在某些方法执行前后插入一些通用的处理,你可以考虑AOP。
预备知识
Proxy
JDK中提供了一个 Proxy
类用于创建动态代理对象的静态方法,如果在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类。 Proxy
提供了下面的方法来创建动态代理实例:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
该代理对象的实现类实现了interfaces所指定的系列接口,执行代理对象的每个方法时都会被替换执行 InvocationHandler
对象的 invoke
方法
InvocationHandler
InvocationHandler是一个接口,在创建动态代理实例的时候需要把一个 InvocationHandler
的实现类传进去,那么执行代理对象的每个方法时就会被替换成执行InvocationHandler实现类中的invoke方法,至于这个invoke方法要怎么实现,就由用户自己决定。
反射中Method的invoke()
在 java.lang.reflect.Method
包中有一个方法
public Object invoke(Object obj, Object... args)
该方法可以实现对象方法的调用,它是 Method
类的实例方法,该方法中的参数 obj
是调用方法的对象, args
是用于方法调用的参数。
实现过程
Pig接口,就定义了两个方法
public interface Pig { void info(); void run(); } 复制代码
Pig的实现类,我们要做的就是在这两个方法执行的前后插入自己一些额外的操作
public class FatPig implements Pig { @Override public void info() { System.out.println("我是一头小肥猪!"); } @Override public void run() { System.out.println("我要跑步啦!"); } } 复制代码
LogUtils,需要在代理对象方法执行前后调用的方法
public class LogUtils { public void before() { System.out.println("==== 方法开始执行 ===="); } public void after() { System.out.println("==== 方法执行结束 ===="); } } 复制代码
PigInvocationHandler,该类实现了InvocationHandler接口。我们定义了一个Object类型的实例变量,因为我们需要在invoke方法中调用被代理对象的实现类的对应的方法。在invoke方法中,有两个关键的参数: method
代表正在执行的方法, args
代表调用目标方法时传入的实参。然后我们就可以在执行代理对象的方法前后自由插入自己的方法了。
public class PigInvocationHandler implements InvocationHandler { // 需要被代理的对象 private Object target; public void setTarget(Object target) { this.target = target; } // 执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { LogUtils logUtils = new LogUtils(); // 执行logUtils对象中的before方法 logUtils.before(); // 以target作为主调来执行method方法 Object result = method.invoke(target, args); // 执行logUtils对象中的after方法 logUtils.after(); return result; } } 复制代码
测试类
public class MyProxyFactory { // 为指定的target生成动态代理对象 public static Object getProxy(Object target) { PigInvocationHandler handler = new PigInvocationHandler(); // 为handler设置target对象 handler.setTarget(target); // 创建并返回一个动态代理 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); } public static void main(String[] args) throws Exception { // 创建一个原始的FatPig对象,作为target Pig target = new FatPig(); // 以指定的target来创建动态代理对象 Pig pig = (Pig) MyProxyFactory.getProxy(target); pig.info(); pig.run(); } } 复制代码
运行结果:
==== 方法开始执行 ====
我是一头小肥猪!
==== 方法执行结束 ====
==== 方法开始执行 ====
我要跑步啦!
==== 方法执行结束 ====
上面实现了简单的AOP功能,我们可以在invoke方法里面加上更多的判断,使得功能更加强大,例如可以根据method参数指定某些方法前后执行特殊的处理。
以上所述就是小编给大家介绍的《来,带你手撕一个AOP》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
SSA:用户搜索心理与行为分析
[美] 罗森菲尔德(Louis Rosenfeld) / 汤海、蔡复青 / 清华大学出版社 / 2014-4-1 / 59.00
何为站内搜索分析(SSA)?它如何帮助你挖掘用户搜索曰志,从中洞悉用户搜索心理和行为,从而有针对性地改善用户体验,提升网站价值?这些都可以从《SSA:用户搜索心理与行为分析》中找到答案。《SSA:用户搜索心理与行为分析》首先通过故事来说明SSA是如何使Vanguard集团起死回生的,简要介绍SSA并指导读者动手实践。其次,通过丰富的实例来介绍很多工具和方法,帮助读者着手分析用户查询数据,从中获得更......一起来看看 《SSA:用户搜索心理与行为分析》 这本书的介绍吧!