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(); } }