Spring AOP配置

前文介绍了Spring AOP的一些概念,本文主要介绍Spring AOP的使用方式:基于注解和xml配置

代理原则

Spring AOP 框架对 AOP 代理类的处理原则是:如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类(可以强制使用CGLIB生成代理,设置proxy-target-class=true)

注解配置

注解配置AOP(使用 AspectJ 类库实现的),大致分为三步:

  1. 使用注解@Aspect来定义一个切面,在切面中定义切入点@Pointcut,通知类型@Before@AfterReturning@After@AfterThrowing@Around
  2. 开发需要被拦截的类(普通的业务逻辑)
  3. 将切面配置到xml中,也可以使用自动扫描Bean的方式,这样切面bean交由Spring IOC容器管理。

注意:Spring只是使用了和 AspectJ 一样的注解,底层依然使用的是 Spring AOP,依然是在运行时动态生成代理

  • 依赖jar包

要想使用@Aspect注解,需要引用 aspectJ 的jar包: aspectjweaver.jaraspectjrt.jar

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
  • 定义接口
1
2
3
4
public interface SimpleService {
public String sayHello(String message);
}
  • 目标类
1
2
3
4
5
6
7
8
public class SimpleServiceImpl implements SimpleService {
@Override
public String sayHello(String message) {
System.out.println("SimpleService : Method sayHello() : Hello! " + message);
return message;
}
}
  • 切面类`
1
2
3
4
5
6
7
8
9
@Component
@Aspect
public class DoBeforeAspect {
@Before("execution(* com.zsr.test.aop.SimpleService.sayHello(..))")
public void doBefore(JoinPoint joinPoint) {
System.out.println("***AspectJ*** DoBefore() is running!! intercepted : " + joinPoint.getSignature().getName());
}
}
  1. @Aspect:意思是这个类为切面类
  2. @Componet:因为作为切面类需要 Spring 管理起来,所以在初始化时就需要将这个类初始化加入 Spring IOC 的管理;
  3. @Befoe:切入点的逻辑(Advice)
  4. execution…:切入点语法
  • 启动注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"
default-lazy-init="false">
<!-- 注意需要添加aop schema -->
<!-- 自动扫描 -->
<context:component-scan base-package="com.zsr.test.aop" />
<!-- 启动 @AspectJ 支持 -->
<aop:aspectj-autoproxy />
</beans>
  • 执行结果
1
2
3
4
---------------
***AspectJ*** DoBefore() is running!! intercepted : sayHello
SimpleService : Method sayHello() : Hello zsr
---------------

xml配置

使用xml配置aop需要用到标签:<aop:config>

  • 配置
1
2
3
4
5
6
7
8
9
10
<!-- 自动扫描 -->
<context:component-scan base-package="com.zsr.test.aop" />
<aop:config>
<aop:aspect id="aspects" ref="doBeforeAspect">
<aop:pointcut id="pointCutBefore"
expression="execution(* com.zsr.test.aop.SimpleService.sayHello(..))" />
<aop:before method="doBefore" pointcut-ref="pointCutBefore" />
</aop:aspect>
</aop:config>
  • 执行结果
1
2
3
4
---------------
***AspectJ*** DoBefore() is running!! intercepted : sayHello
SimpleService : Method sayHello() : Hello zsr
---------------

参考

Spring AOP 实现原理与 CGLIB 应用

spring aop两种配置方式

Spring AOP AspectJ Example

热评文章