Spring 基于XML配置的AOP框架详细讲解
Posted 张梦源
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 基于XML配置的AOP框架详细讲解相关的知识,希望对你有一定的参考价值。
学习Spring中的AOP,就是通过配置的方式(有基于XML配置的, 以及基于注解配置的),来实现相关的拦截切入功能。对原有的操作进行加强,但不影响原本的操作。
目录
学习Spring中的AOP,就是通过配置的方式(有基于XML配置的, 以及基于注解配置的),来实现相关的拦截切入功能。对原有的操作进行加强,但不影响原本的操作。
1.理解:Aop进行的加强就是如此,你仅仅是想要查询用户,但是在你进行的过程中我对你的过程进行的扩充操作。(小编个人的理解)
1.理解:Aop进行的加强就是如此,你仅仅是想要查询用户,但是在你进行的过程中我对你的过程进行的扩充操作。(小编个人的理解)
2.必须的jar包
3.大致分为两类进行学习
(1)前置,后置,异常,最终
- 前置通知:在切入点方法执行之前执行
- 后置通知:在切入点方法正常执行之后执行。它和异常通知永远只能执行一个
- 异常通知:在切入点方法执行产生异常之后执行。它和后置通知永远只能执行一个
- 最终通知:无论切入点方法是否正常执行它都会在其后面执行
(2)环绕
- 前面是通过配置的方式指定增强的代码何时执行,而现在是通过代码控 制的方式来指定增强的代码何时执行。
- 所以说环绕通知是Spring框架提供的一种可以在代码中手动控制增强方法何时执行的方式。
4.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
https://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="userServiceImpl"
class="com.bookmanagesystem.service.impl.UserServiceImpl"></bean>
<bean id="mylogger"
class="com.bookmanagesystem.util.MyLogger">
</bean>
<aop:config>
<aop:pointcut
expression="execution(* com.iflytek.bookmanagesystem.service.impl.*.*(..) )"
id="pc1" />
<!-- 3. 配置切面 -->
<aop:aspect id="logAdvice" ref="mylogger">
<!-- 配置通知的类型 (原始方法) -->
<!-- <aop:before method="printLog" pointcut-ref="pc1" /> <aop:after-returning method="printLog" pointcut-ref="pc1" /> -->
<!-- <aop:before method="printLog" pointcut="execution(public void com.bookmanagesystem.service.impl.UserServiceImpl.delete()
)" /> -->
<!-- 1. 配置前置通知 -->
<!-- <aop:before method="beforePrintLog" pointcut-ref="pc1" /> -->
<!-- 2. 配置后置通知 -->
<!-- <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pc1"
/> -->
<!-- 3. 配置异常通知 -->
<!-- <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pc1"
/> -->
<!-- 4. 配置最终通知 -->
<!-- <aop:after method="afterPrintLog" pointcut-ref="pc1" /> -->
<!-- 5. 配置环绕通知 -->
<aop:around method="aroundPrintLog" pointcut-ref="pc1" />
</aop:aspect>
</aop:config>
</beans>
5.main函数调用
public static void main(String[] args) {
// 1. 获取核心容器对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 根据id获取bean对象
IUserService service = (IUserService) context.getBean("userServiceImpl");
service.update();
// 3.关闭容器(如果不记得关闭容器,最典型的问题就是数据库连接不能释放)
((ClassPathXmlApplicationContext) context).close();
}
6.IUserService接口
public interface IUserService {
void update();
// 模拟更新用户操作
}
7.IUserService接口实现类
public class UserServiceImpl implements IUserService {
//模拟的
@Override
public void update() {
System.out.println("进行修改用户的操作");
}
}
8.织入文件MyLogger
public class MyLogger {
/**
* 用于打印日志,并且让其在切入点方法执行之前执行(切入点方法就是业务方法)
*/
// 前置通知
public void beforePrintLog() {
System.out.println("前置通知MyLogger类中的beforePrintLog方法开始记录日志了。。。");
}
// 后置通知
public void afterReturningPrintLog() {
System.out.println("后置通知MyLogger类中的afterReturningPrintLog方法开始记录日志了。。。");
}
// 异常通知
public void afterThrowingPrintLog() {
System.out.println("异常通知MyLogger类中的afterThrowingPrintLog方法开始记录日志了。。。");
}
// 最终通知
public void afterPrintLog() {
System.out.println("最终通知MyLogger类中的afterPrintLog方法开始记录日志了。。。");
}
//环绕通知
public Object aroundPrintLog(ProceedingJoinPoint pjp) {
Object result = null;
try {
Object[] args = pjp.getArgs(); // 得到方法执行所需的参数
System.out.println("环绕通知记录日志前置");
result = pjp.proceed(args); // 明确调用业务层方法(切入点方法)
System.out.println("环绕通知记录日志后置");
return result;
} catch (Throwable e) { // proceed方法抛出了Throwable,这里用Exception拦不住
System.out.println("环绕通知记录日志异常");
e.printStackTrace();
throw new RuntimeException(e);
} finally {
System.out.println("环绕通知记录日最终");
} }
}
9.aop配置解释:
<aop:config>//表明我开始配置Aop了
<aop:pointcut expression="execution(* com.bookmanagesystem.service.impl.*.*(..) )"
id="pc1" />//1.一种简单的写法也可以写成上面具体的 2.把我bookmanagesystem.service.impl.UserServiceImpl.包下面所有的方法我都给他起了一个名字叫做“pc1”
<!-- 3. 配置切面 -->
<aop:aspect id="logAdvice" ref="mylogger">//ref 让我的切面和织入文件联系起来好进行加强操作
<aop:around method="aroundPrintLog" pointcut-ref="pc1" />//环绕调用的方法即是我MyLogger类中的public Object aroundPrintLog(ProceedingJoinPoint pjp) {}方法,因为pc1包含了所有包com.bookmanagesystem.service.impl.下我写的方法
</aop:aspect>
</aop:config>
10.切入点表达式(* 的使用)
以上是关于Spring 基于XML配置的AOP框架详细讲解的主要内容,如果未能解决你的问题,请参考以下文章