学习Spring AOP之前,先了解一下AOP的底层实现:代理模式。
AOP(Aspect-oriented Programming):面向切面编程,是Spring的关键组件之一。
通过预编译方式和运行时动态代理实现程序功能的统一维护。
AOP 在 Spring 框架中的作用:
目标对象(Target object):被通知的对象,也称为通知对象;
连接点(Join point):程序执行过程中的一个点,是目标对象的一个方法或异常处理;
横切关注点:跨越多个类的方法或功能。即与业务逻辑无关,但是需要关注的部分(如安全、日志、缓存、事务等);
切面(Aspect):横切关注点的模块化,是一个类;
通知(Advice):切面在连接点采取的行动,它是类的一个方法;
切入点(Pointcut):匹配连接点,是通知执行的 ”地点“;
AOP 代理(AOP proxy)**:AOP 创建的对象,用于执行通知的方法等;
编织(Weaving):将切面与其他应用程序或对象联系起来,以创建目标对象,在运行时执行。
Advice 类型:
通知类型 | 执行点 | 实现接口 |
---|---|---|
前置通知(Before) | 连接点之前(方法前) | org.springframework.aop.MethodBeforeAdvice |
后置通知(After / Finally) | 连接点之后(方法后) | org.springframework.aop.AfterAdvice |
返回后通知(After returning) | 连接点正常完成后(方法后) | org.springframework.aop.AfterReturningAdvice |
环绕通知(Around) | 环绕连接点(方法前) | org.springframework.aop.aspectj.AspectJAroundAdvice |
抛出后通知(After throwing) | 方法抛出异常 | org.springframework.aop.ThrowsAdvice |
需求:为 CRUD操作添加通知(前、后)。
导入编织依赖
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
<scope>runtime</scope>
</dependency>
引入 Spring 配置信息
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd"
public interface UserService {
/**
* 增加
*/
void insert();
/**
* 删除
*/
void delete();
/**
* 更新
*/
void update();
/**
* 查询
*/
void query();
}
public class UserServiceImpl implements UserService {
@Override
public void insert() {
System.out.println("----增加一个用户----");
}
@Override
public void delete() {
System.out.println("----删除一个用户----");
}
@Override
public void update() {
System.out.println("----更新一个用户----");
}
@Override
public void query() {
System.out.println("----查询一个用户----");
}
}
public class LogAfterReturningAdvice implements AfterReturningAdvice {
/**
* 后置通知
*
* @param returnValue 方法的返回值
* @param method 目标对象的方法
* @param args 参数
* @param target 目标对象
* @throws Throwable
*/
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("返回后通知:"
+ target.getClass().getName()
+ "的" + method.getName()
+ "方法被执行了,返回值为"
+ returnValue);
}
}
applicationContext.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: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="indi.jaywee.service.UserServiceImpl"/>
<bean id="logAfterReturning" class="indi.jaywee.Utils.LogAfterReturningAdvice"/>
<!-- 配置AOP -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut id="pointcut" expression="execution(* indi.jaywee.service.UserServiceImpl.* (..))"/>
<!-- 通知 -->
<aop:advisor advice-ref="logAfterReturning" pointcut-ref="pointcut"/>
</aop:config>
</beans>
注意:
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 错误写法:
// UserService userService = context.getBean("userService", userServiceImpl.class);
// 正确写法
UserService userService = context.getBean("userService", UserService.class);
// 另一种正确写法
// UserService userService = (userService) context.getBean("userService");
userService.insert();
userService.delete();
userService.update();
userService.query();
}
简单理解如下:
原文:https://www.cnblogs.com/secretmrj/p/15106653.html