AOP编程(aspect oriented program)面向切面编程
A) 静态代理设计模式
现实生活中的场景:
概念:通过代理类为原始类增加额外功能。
好处:避免原始类因为额外功能频繁被修改,从而使代码更加利于维护。
名词解释:
1. 原始类或者目标类(target):那些只负责核心功能,没有加入额外功能的类。纯净的Service。
2. 原始功能,原始方法:原始类中的方法,没有加入额外功能的方法。
3. 额外功能:可有可无的,附加的功能。
代理类本质 = 原始类 + 额外功能 + 实现原始类的相同接口
静态代理设计模式的问题:
1. 代理类的数量过多,不利于项目管理。
2. 额外功能的代码冗余。
3. 替换代理的额外功能太麻烦。
B) Spring的动态代理设计模式
概念:通过代理类为原始类增加额外功能。
好处:利于原始类维护。
动态代理中需要引入额外的两个第三方依赖jar包:
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
1. 开发步骤
A) 创建原始对象(Service没有额外功能)
B) 创建额外功能Advice(接口)
Advice接口有四个子接口:
MethodBeforeAdvice(前置通知)
额外功能需要在原始方法执行之前执行。
AfterReturningAdvice(后置通知)
额外功能需要在原始方法执行之后执行。
MethodInterceptor(环绕通知)
注意:这个接口不是Spring提供的,是AopAliance提供的。
额外功能需要在原始方法执行之前和之后执行(最重要的功能就是控制事务)。
ThrowsAdvice 额外功能需要在原始方法抛出异常时执行。(异常处理通知)
注意:ThrowsAdvice接口是一个没有定义方法的接口,我们称之为TagInterface标志性接口,这种标志性接口还有:Seriazable ThrowsAdvice Remote。
ThrowsAdvice接口的额外功能主要用于事务回滚。
C) 定义切入点(pointcut)
切入点决定了额外功能加入的位置。
1. 方法切入点
定义额外功能需要加入给哪些方法,上面execution(* *(..))就是一个典型的方法切入点。
注意:
切入点表达式最外层是一个切入点函数execution(),这是死的,真正活的是切入点函数里面的切入点表达式。
切入点表达式:* *(..)代表所有方法加入额外功能
按照要求写切入点表达式:
A) 为login方法加入额外功能:* login(..)
B) 为只有一个字符串参数的login方法加入额外功能:
* login(String)
注意:参数是String类型,而String类型是属于java.lang包中的,所以可以直接写String,如果参数不是java.lang包下面的类型,那么参数在书写的时候,必须写全限定名。比如:
* register(com.liw.User)
C) 为有两个字符串类型参数的login方法加入额外功能:
* login(String,String)
D) * login(String,..)表达的含义:login方法参数中第一个参数是String类型的,然后后面的参数没有要求,没有要求的意思是可以有其它参数,并且类型不限,也可以没有其它参数。
2. 类切入点
定义额外功能加入给哪个类,切入点表达式仍然写在execution()函数中。