我对AOP的理解
?
1、问题?
问题:想要添加日志记录、性能监控、安全监测?
?
2、最初解决方案?
2.1、最初解决方案
?缺点:紧耦合,每个业务逻辑需要一个装饰器实现或代理
2.4、JDK动态代理解决方案(比较通用的解决方案)?
public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //1.记录日志 2.时间统计开始 3.安全检查 Object retVal = method.invoke(target, args); //4.时间统计结束 return retVal; } public static Object proxy(Object target) { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new MyInvocationHandler(target)); }}
?编程模型?
//proxy 在其上调用方法的代理实例 //method 拦截的方法 //args 拦截的参数 Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object retVal=null; //预处理 //前置条件判断 boolean ok = true; if(!ok) {//不满足条件 throw new RuntimeException("你没有权限"); } else {//反射调用目标对象的某个方法 retVal = method.invoke(target, args); } //后处理 return retVal; } ?
缺点:使用麻烦,不能代理类,只能代理接口??
?
public class MyInterceptor implements MethodInterceptor { private Object target; public MyInterceptor(Object target) { this.target = target; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy invocation) throws Throwable { //1.记录日志 2.时间统计开始 3.安全检查 Object retVal = invocation.invoke(target, args); //4.时间统计结束 return retVal; } public static Object proxy(Object target) { return Enhancer.create(target.getClass(), new MyInterceptor(target)); }}?编程模型
//proxy 在其上调用方法的代理实例 method拦截的方法 args 拦截的参数 //invocation 用来去调用被代理对象方法的@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy invocation) throws Throwable { //预处理 //前置条件判断 boolean ok = true; if(!ok) {//不满足条件 throw new RuntimeException("出错了"); } else {//调用目标对象的某个方法 Object retVal = invocation.invoke(target, args); } //后处理 return retVal;}
?

?2.5、AOP解决方案(通用且简单的解决方案)
@Aspectpublic class PayEbiAspect { @Pointcut(value="execution(* pay(..))") public void pointcut() {} @Around(value="pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { //1.记录日志 //2.时间统计开始 //3.安全检查 Object retVal = pjp.proceed();//调用目标对象的真正方法 //4.时间统计结束 return retVal; }}//2 切入点 @Pointcut(value="execution(* *(..))") public void pointcut() {} //3 拦截器的interceptor @Around(value="pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { Object retVal=null; //预处理 //前置条件判断 boolean ok = true; if(!ok) {//不满足条件 throw new RuntimeException("你没有权限"); } else {//调用目标对象的某个方法 retVal = pjp.proceed(); } //后处理 return retVal; }?
?
?
AOP开发步骤? 类似于IoC/DI容器开发步骤,需要描述哪个连接点需要哪个通用功能(增强)? 参考:http://www.iteye.com/topic/1122310
横切关注点的表现有:
代码纠结/混乱——当一个模块或代码段同时管理多个关注点时发生这种情况。
代码分散——当一个关注点分布在许多模块中并且未能很好地局部化和模块化时发生这种情况 。AOP包括三个清晰的开发步骤:1:功能横切:找出横切关注点。2:实现分离:各自独立的实现这些横切关注点所需要完成的功能。3:功能回贴:在这一步里,方面集成器通过创建一个模块单元——?方面来指定重组的规则。重组过程——也叫织入或结合——?则使用这些信息来构建最终系统。
推荐阅读书籍:AspectJ in Action
AOSD中文版--基于用例的面向方面软件开发
推荐阅读的帖子:AOP的实现机制
?
文章主要是为了抛砖引玉,希望有更多牛人的指点。