1:AspectJ 框架简介
AspectJ 是一个基于 Java 语言的 AOP 框架。在 Spring 2.0 以后,新增了对 AspectJ 框架的支持。在 Spring 框架中建议使用 AspectJ 框架开发 AOP。
2:依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
AspectJ注解方式
相关注解
@Aspect:作用是把当前类标识为一个切面供容器读取
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行
1:创建被增强类
public class User {
public void add(){
System.out.println("add......");
}
}
2:创建增强类
public class UserProxy {
//前置通知
public void before(){
System.out.println("before@@@");
}
}
3:开启包扫描和开启AspectJ生成代理对象功能
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.dong.entity"/>
<!--开启AspectJ生产代理对象
如果类上有@Aspect注解 就会生成此类的代理对象
-->
<aop:aspectj-autoproxy/>
</beans>
给增强类和被增强类添加注解
被增强类
@Component
public class User {
public void add(){
System.out.println("add......");
}
}
增强类
@Component
@Aspect //生产代理对象
public class UserProxy {
//前置通知
public void before(){
System.out.println("before@@@");
}
}
4:配置通知
1:在增强类中,在作为通知方法上面添加通知类型注解(使用切入点表达式)
@Component
@Aspect //切面
public class UserProxy {
//前置通知
// public(权限修饰符可以省略) *代表可以是 任何的返回值类型(不能省略)
@Before("execution(public * com.dong.entity.User.add())")
public void before(){
System.out.println("before@@@");
}
//后置通知 add(..)表示0个或多个参数 0也表示
@AfterReturning("execution(* com.dong.entity.User.add(..))")
public void afterReturning(){
System.out.println("afterReturning");
}
//最终通知
@After("execution(* com.dong.entity.User.add())")
public void after(){
System.out.println("after");
}
//异常通知
@AfterThrowing("execution(* com.dong.entity.User.add())")
public void afterThrowing(){
System.out.println("afterThrowing");
}
}
2:测试
public class Test1 {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
user.add();
}
}
/*
before@@@
add......
afterReturning
after
*/
3:可以把Aspect表达式中公共的部分提取出来
@Component
@Aspect //生产代理对象
public class UserProxy {
//相同切入点抽取
//execution(public * com.dong.entity.User.add())
@Pointcut("execution(public * com.dong.entity.User.add())")
public void pointDemo(){
}
//前置通知
// public(权限修饰符可以省略) *代表可以是 任何的返回值类型(不能省略)
@Before("pointDemo()")
public void before(){
System.out.println("before@@@");
}
//后置通知 add(..)表示0个或多个参数 0也表示
@AfterReturning("pointDemo()")
public void afterReturning(){
System.out.println("afterReturning");
}
//最终通知
@After("pointDemo()")
public void after(){
System.out.println("after");
}
//异常通知
@AfterThrowing("pointDemo()")
public void afterThrowing(){
System.out.println("afterThrowing");
}
}
4:多个增强类设置优先级
@Order(1); 在增强类上使用此注解 数字越小,优先级越高