Spring AOP框架提供了一种面向切面编程的方法。之前如果我们要给一个类添加日志功能,记录方法的调用,异常情况,我们需要在类中去写无数的log,这样不仅使得代码混乱,不易维护,也使得代码复用性降低。
现在我们有了AOP,就可以解决这些问题。
从一个现实例子入手,观众去看演唱会,观众在歌手上舞台之前,要入座,歌手开始唱歌,如果唱的好观众会鼓掌,唱的不好,观众会吐槽,唱完之后,观众会离场。观众的这一切行为,都是因歌手而产生,但是歌手却不必关心观众的行为,也不用主动让观众鼓掌,歌手就做好他的唱歌工作就好。在这个例子中,观众就是切面,记录着歌手的行为,并做出相应反应。
下面看代码实例
Singer.java
package com.aop;
import org.springframework.stereotype.Component;
@Component//将歌手类生成bean
public class Singer {
public void sing(){
System.out.println("sing");
}
}
可以看出,歌手类的代码很简洁,他并不需要管其它事情(如主动让观众鼓掌)。
Audience.java
package com.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect//将观众声明为切面
public class Audience {
//定义切点,不能把本切面中的方法包括进去,不然会循环注入
@Pointcut("execution( * com.aop.Singer.sing(..))" )
public void singer(){}//切点表达式
@Before("singer()")//调用方法前执行的通知
public void before(){
System.out.println("before");
}
@After("singer()")//调用方法后执行的通知
public void after(){
System.out.println("after");
}
@AfterReturning("singer()")//调用方法返回后执行的通知
public void afterReturning(){
System.out.println("afterReturning");
}
@AfterThrowing("singer()")//调用方法抛出异常执行的通知
public void afterThrowing(){
System.out.println("afterThrowing");
}
@Around("singer()")//环绕通知
public void around(ProceedingJoinPoint pjp){
try{
System.out.println("around-before");
pjp.proceed();
System.out.println("around-after");
}catch (Throwable e){
e.printStackTrace();
}
}
}
观众就是一个切面。观众主动根据歌手执行的方法,做出响应。
配置文件:
package com.aop;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy//启用AspectJ注解的自动代理
public class Config {
@Bean//声明Audience bean
public Audience audience(){
return new Audience();
}
}