AOP前置通知
前置通知:在方法之前执行的通知,使用`@Before`注解并将切入点表达式的值作为注解值。
- 使用Maven添加依赖的jar包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
- 继续使用上节中的
ArithmeticCalculator
和ArithmeticCalculatorImpl
类。 - 新建一个
LoggingAspect
切面类:
其中@Component
注解标注为一个被Spring管理的bean,@Aspect
将类标注为切面类;execution(* com.fafa.spring.aop.impl.*.*(..))
为execution(public int com.fafa.spring.aop.impl.ArithmeticCalculator.add(int, int))
的抽象精简写法,第一个*
代表匹配任意修饰符及任意返回值,第二个*
表示com.fafa.spring.aop.impl
包中的任意类,第三个*
表示类中的任意方法,括号中的..
表示方法的任意参数。
@Component
@Aspect
public class LoggingAspect {
@Before("execution(* com.fafa.spring.aop.impl.*.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("The method" + methodName +" begins..." + args);
}
}
JoinPoint
参数表示连接点,可以获取到方法名和参数。 - 创建一个Spring配置文件
applicationContext.xml
使用@AspectJ
注解会自动为匹配的类生成代理对象:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com.fafa.spring.aop.impl"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
- 创建测试类:
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
int result = arithmeticCalculator.add(3, 6);
System.out.println("result:" + result);
result = arithmeticCalculator.div(6, 3);
System.out.println("result:" + result);
}
}
测试结果:在方法返回值前都添加了相应的信息The methodadd begins...[3, 6]
result:9
The methoddiv begins...[6, 3]
result:2
后置通知
- 使用
@After
注解标注,在LoggingAspect
类中添加如下方法:
@After("execution(* com.fafa.spring.aop.impl.*.*(..))")
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" ends...");
}
- 运行结果:
The methodadd begins...[3, 6]
The method add ends...
result:9
The methoddiv begins...[6, 3]
The method div ends...
result:2
afterMethod
方法结束,此时还无法在结束时获取到返回的结果,后面可以使用返回通知获取到返回值。