二、AOP
A、AOP:Aspect Oriented Programming
引入aspectjweaver和aopalliance的包
JoinPoint 连接点
PointCut 切入点(连接点集合)(切入点一般是定义在方法上,其实也可以在属性甚至类上)
Aspect 方面(切面类)
Advice 切面对于某个“连接点”所产生的动作,before、after、around(切入点建议)
Target 被织入的对象(被一个或者多个切面所通知的对象)
Weaving 织入
AspectJ语法:?代表0或1次 *代表任意
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
modifiers-pattern:方法的访问修饰
ret-type-pattern:返回值 *
declaring-type-pattern:方法所在的包及类 *
name-pattern:方法名 *
param-pattern:参数名 …
throws-pattern:异常
execution(public * com.cssl.service…*.add(…))
B、Annotation配置:
另外转二进制包cglib(无接口的类被代理的情况下使用,Spring3.2以上已经集成此包)
测试类名可以得出结论:(service.getClass());
1、xml中必须加aop:aspectj-autoproxy/
2、类上加@Component、@Aspect(切面逻辑)
3、织入方法上写@Before(“execution(public void com.cssl….(com.pojo.Users))”)
4、也可以使用@AfterReturning|@After|@Around|@AfterThrowing
5、@AfterReturning只有方法没有抛出异常的情况下执行,不管是否有返回值
6、切面类上加@Order(1)决定切面执行顺序
注意:
1、Spring提供的环绕处理类:
ProceedingJoinPoint(不能使用父接口JoinPoint,接口没有proceed()方法)
public void around(ProceedingJoinPoint pjp) throws Throwable{
…
//这里如果异常是自己处理了则@AfterThrowing捕获不到service方法抛出的异常
pjp.proceed();
…
}
2、@AfterThrowing要起作用必须是该Pointcut方法上抛出异常
@AfterThrowing(pointcut=“cut()”,throwing=“e”)
public void doException(Exception e) {
System.out.println(“出异常咯:”+e.getMessage());
}
3、写通用织入方法:
@Pointcut(“execution(public * com.cssl….(…))”)
public void cutAll(){};
4、其他方法引入该织入点11.2.4
@Before(“cutAll()”) || @Before(“Logger.cutAll()”)
public void before(){}
5、拦截含有参数的方法,并将参数值注入到当前方法的形参id,name中
@Before(“cutAll() && args(id,name)”)
public void before(int id,String name)
public void before(JoinPoint jp):jp.getArgs()
6、获取被切入方法的返回值
@AfterReturning(pointcut=“cutAll()”,returning=“result”)
public void afterReturn(JoinPoint jp,Object result)
C、xml配置:在切面逻辑是第三方提供的情况下只能使用xml
aop:config
<aop:pointcut expression=“execution(* com.cssl.service….add(…))" id=“cutAll”/>
<aop:aspect ref=“logInfo”>
<aop:before method=“before” pointcut="execution(public * com….*(int)) and args(id)” />
<aop:after-returning method=“afterReturn” pointcut-ref=“cutAll” returning=“result”/>
</aop:aspect>
</aop:config>
D、Spring的AOP实现:4种(没有AfterAdvice)
MethodBeforeAdvice
前置通知: 在某连接点JoinPoint之前执行的通知,但这个通知不能阻止连接点前的执行。
AfterReturningAdvice
返回后通知:在某连接点正常完成后执行的通知,不包括抛出异常的情况。
MethodInterceptor(导入aopalliance包的接口)
环绕通知: 包围一个连接点的通知,类似Web中的Filter的doFilter方法。
ThrowsAdvice
异常通知: 在方法抛出异常退出时执行的通知。
必须使用下面的方法签名:(Throwable e必须有,而且方法可以写多个)
void afterThrowing([Method method, Object[] arguments, Object target,] Throwable ex)
使用:(注意advice-ref引用的bean必须是Advice接口的实现类)
aop:config
<aop:pointcut expression=“execution(public * com.cssl.service….(…))” id=“cut”/>
<aop:advisor advice-ref=“myBeforeAdvice” pointcut-ref=“cut”/>
</aop:config>
Filter和Interceptor都应用了面向切面编程思想