一、什么是SpringAOP
AOP就是在某一个类或方法执行前后打个标记,声明在执行到这里之前要先执行什么,执行完这里之后要接着执行什么。
二、AOP术语
1)连接点(Joinpoint)
通知分为
前置通知:before 在方法执行之前执行
后置通知:after 在方法执行之后执行(不管方法执行成功还是失败)
返回通知:afterReturning 在方法执行成功后执行
异常通知:afterThrowing 在方法发生异常后执行
环绕通知:around 在方法执行前后执行
三、Spring对AOP的支持
1.使用ProxyFactoryBean和对应的接口实现AOP
2.使用XML配置AOP
3.使用@AspectJ注解驱动切面
4.使用AspectJ注入切面
四、使用@AspectJ注解开发AOP(优先)
0.Spring实现的是一个方法级别的AOP框架,动态代理的方式拦截指定方法的通知
1.创建切面
在Spring中使用@Aspect注解一个类,SpringIOC容器就会将其当作一个切面。
切面类中的方法可以通过加上以下注解作为通知
@Before 前置通知
@After 后置通知
@Around 环绕通知
@AfterReturning 正常返回通知
package club.llf.aspect; import org.aspectj.lang.annotation.*; @Aspect public class XXXAspect { @Before("execution(* club.llf.service.impl.UserServiceImpl.printUser(..))") public void before(){ System.out.println("前置通知"); } @After("execution(* club.llf.service.impl.UserServiceImpl.printUser(..))") public void after(){ System.out.println("后置通知"); } @AfterReturning("execution(* club.llf.service.impl.UserServiceImpl.printUser(..))") public void afterReturning(){ System.out.println("返回通知"); } @AfterThrowing("execution(* club.llf.service.impl.UserServiceImpl.printUser(..))") public void afterThrowing(){ System.out.println("异常通知"); } }
execution : 执行方法时触发
* : 任意返回值的方法
club.llf.service.impl.UserServiceImpl.printUser : 拦截指定方法名
(..) : 方法的参数任意
3.为了少写重复的正则表达式,可以使用@Pointcut注解来避免,修改如下
package club.llf.aspect; import org.aspectj.lang.annotation.*; @Aspect public class XXXAspect { @Pointcut("execution(* club.llf.service.impl.UserServiceImpl.printUser(..))") public void print(){ } @Before("print()") public void before(){ System.out.println("前置通知"); } @After("print()") public void after(){ System.out.println("后置通知"); } @AfterReturning("print()") public void afterReturning(){ System.out.println("返回通知"); } @AfterThrowing("print()") public void afterThrowing(){ System.out.println("异常通知"); } }
五、开启AOP自动代理
1.注解方式
注解配置类如下(也可以给切面类加上@Component,并且扫描其所在包,那么就可以不配置下面的@Bean了)
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages={"club.llf.pojo"})
public class AOPConfig{
@Bean
public RoleAspect getRoleAspect(){
return new XXXAspect();
}
}
2.XML方式定义切面
<aop:aspectj-autoproxy/>
<bean id="xxxAspect" class="club.llf.aspect.XXXAspect"/>
....