核心
- 前提:IOC环境
- AOP的核心思想:配置AOP的核心在于将我们编写的切面类的某个方法注入到目标类的某个方法前或者后进行拦截
- AOP的具体实现:导入jar包,编写目标类和切面类并注册到Spring容器中,通过xml或者注解的方式进行AOP开发的 配置,最后进行单元测试
基础
1.什么是AOP,为什么要学习Spring的AOP机制:
AOP全称面向切面编程,Spring通过动态代理进行底层AOP的实现。代理框架已经帮我们写好了,我们只需要针对开发进行相应的配置即可。
AOP可以进行权限校验、日志记录、性能监控、事务控制等
2.Spring的AOP底层实现
- JDK动态代理-类实现接口时底层自动调用该动态代理方式
- Cglib动态代理-类未实现接口时自动调用该动态代理方式
3.AOP的相关术语:
- Joinpoint:连接点,可以被拦截到的点。增删改查的方法都可以被增强,这些方法就可以称为是连接点
- Pointcut:切入点,真正被拦截到的点。例如在实际开发中只对save方法进行增强,那么save就称为是切入点。
- Advice:通知、增强。例如现在 对save方法进行权限校验,权限校验的方法就称为是通知
- Introduction:引介,类层面的增强
- Targer:被增强的对象,对某个类进行增强,那么这个类曾为是目标
- Weaving:植入,将通知(Advice)应用到切入点(Pointcut)的过程
- Proxy:代理对象
- Aspect:切面,多个通知和多个切入点组合!
4.通知类型:
- 前置通知:在目标方法执行之前进行操作-可以通过参数获得切入点信息
- 后置通知:在目标方法执行之后进行操作-可以通过配置获得方法的返回值
- 环绕通知:在目标方法执行之前和之后进行操作
- 异常抛出通知:在程序出现异常的时候进行的操作-可以通过配置获取异常信息
- 最终通知:不论代码是否有异常,总是会执行
5.Spring的AOP注解开发详解
前提:首先在配置文件中开启注解的AOP的开发
例如:<aop:aspectj-autoproxy/>
- @Aspect:表明该类是一个切面类
- @Before:表明该方法作为某些目标类下的某些方法的前置通知
- @AfterReturning:后置通知
- @Around:环绕通知
- @AfterThrowing:异常抛出通知
- @After:最终通知
- @Pointcut:切入点注解
附录一:基于xml方式的AOP配置文件
项目地址:
- 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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置目标类:被增强的对象 -->
<bean id = "productDao" class = "com.cyn.spring.demo1.ProduceDaoImpl"/>
<!-- 配置切面类 :执行通知的类-->
<bean id = "myAspect" class = "com.cyn.spring.demo1.MyAspectXML"/>
<!-- 通过AOP的配置完成对目标类产生代理,即将我们编写的切面类注入到目标类 -->
<aop:config>
<!-- 表达式来配置哪些类的哪些方法需要增强 -->
<!--
*:代表任意返回值类型
..:代表任意形参
-->
<aop:pointcut expression="execution(* com.cyn.spring.demo1.ProduceDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* com.cyn.spring.demo1.ProduceDaoImpl.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* com.cyn.spring.demo1.ProduceDaoImpl.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* com.cyn.spring.demo1.ProduceDaoImpl.find(..))" id="pointcut4"/>
<!-- 配置切面:将我们编写的某个切面类的某个方法注入到目标类的某个方法前或者后 -->
<aop:aspect ref="myAspect">
<!-- 前置通知 -->
<aop:before method="checkPri" pointcut-ref="pointcut1"/>
<!-- 后置通知:包括目标方法的返回值获取 -->
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
<!-- 异常抛出通知:包括异常信息的打印 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
</beans>
附录二:基于注解方式的AOP配置文件
项目地址:
- 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: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">
<!-- 在配置文件中开启注解的AOP的开发 -->
<aop:aspectj-autoproxy/>
<!-- 配置目标类 -->
<bean id = "orderDao" class = "com.cyn.spring.demo1.OrderDao"/>
<!-- 配置切面类 -->
<bean id = "myAspect" class = "com.cyn.spring.demo1.MyAspectAnno"/>
</beans>