AOP:全称是AspectOriented Programming, 即面向切面编程。在不修改源码的基础上,对我们的已有方法进行增强。就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,进行增强。在程序运行期间,不修改源码对已有方法进行增强。
实现步骤:
-
导入坐标
pom.xml
<dependencies>
<!--Spring核心容器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringAOP相关的坐标-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!--Spring整合单元测试-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
-
定义被增强的业务逻辑类和切面类
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("执行添加...");
}
}
MyAspect.java
public class MyAspect {
public void checkPermission(){
System.out.println("进行权限校验....");
}
}
-
配置AOP
spring-aop.xml
<?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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="cn.appmy"></context:component-scan>
<aop:config>
<aop:pointcut id="pc1" expression="execution(* cn.appmy.service.impl.UserServiceImpl.*(..))"/>
<aop:aspect id="a1" ref="myAspect">
<aop:before method="checkPermission" pointcut-ref="pc1"></aop:before>
</aop:aspect>
</aop:config>
</beans>
附录:切入点表达式规则
-
执行任何公有方法
execution(public * *(..))
-
执行任何以
set
开头的方法execution(* set*(..))
-
执行com.xyz.service.AccountService类中的任何方法(执行某个类的任何方法)
execution(* com.xyz.service.AccountService.*(..))
-
执行当前包下类的任意方法(不含子包)
execution(* com.xyz.service.*.*(..))
-
执行当前包及其子包下类的任意方法
execution(* com.xyz.service..*.*(..))
-
执行当前包下类的任意方法(不含子包)
within(com.xyz.service.*)
-
执行当前包及其子包下类的任意方方法
within(com.xyz.service..*)
-
实现当前接口的类的任何方法
this(com.xyz.service.AccountService)
-
实现当前接口的类的任何方法
target(com.xyz.service.AccountService)
-
只有一个参数且实现了Serializable的任何方法
args(java.io.Serializable)
-
有Transactional注解标签的方法(针对特定注解标签)
@target(org.springframework.transaction.annotation.Transactional)
-
有Transactional注解标签的方法(针对特定注解标签)
@within(org.springframework.transaction.annotation.Transactional)
-
有Transactional注解标签的方法(针对特定注解标签)
@annotation(org.springframework.transaction.annotation.Transactional)
-
只有一个参数且参数有Classified注解的任何方法
@args(com.xyz.security.Classified)
-
指定名称的bean下任意方法
bean(tradeService)
-
满足通配符命名的bean下任意方法
bean(*Service)