前言
- AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
SpringAop的意义:
- 将除了核心业务以外的一些经常用的模块给抽出来,形成切面,例如,将权限,日志、事务单独抽出来,形成切面,让这些单独的模块与系统变得 松耦合。
SpringAop的各个概念:
- 切面(Aspect):官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类Transaction类,在ApplicationContext中用
来配置。<aop:aspect>
- 连接点(Joinpoint):程序执行过程中的某一行为,客户端调用哪个方法,哪个方法就是连接点,例如,
方法。personDao.savePerson()
- 通知(Advice) :“切面”对于某个“连接点”所产生的动作,例如,Transaction类中对
包下所有类的方法进行动作就是一个Advice。其中,一个“切面”可以包含多个“Advice”,例如com.spring.aop.xml.transaction.PersonDaoImpl
等等。beginTransaction()、commit()
- 切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联。例如,Transaction中的所有通知所关注的连接点,都由切入点表达
来决定。expression="execution(*com.spring.aop.xml.transaction.PersonDaoImpl.*(..))"
- 目标对象(Target Object) :被一个或者多个切面所通知的对象。例如,PersonDaoImpl,当然在实际运行时,Spring AOP采用代理实现,实际AOP操作的是TargetObject的代理对象。
- AOP代理(AOP Proxy) :在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理,反之,采用CGLIB代理。强制使用CGLIB代理需要将
的<aop:config>
属性设为proxy-target-class
。true
代码展现
配置文件
<bean id="personDao" class="com.spring.aop.xml.transaction.PersonDaoImpl"></bean>
<bean id="transaction" class="com.spring.aop.xml.transaction.Transaction"></bean>
<aop:config>
<!--
切入点表达式 确定目标类
-->
<aop:pointcut expression="execution(* com.spring.aop.xml.transaction.PersonDaoImpl.*(..))"id="perform"/>
<!--
配置切面,ref指向的对象就是切面
-->
<aop:aspect ref="transaction">
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<aop:after-returning method="commit" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
切面类
public class Transaction {
public void beginTransaction(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
}
目标类
public class PersonDaoImpl implements PersonDao{
public void savePerson() {
System.out.println("save person");
}
}
测试类
public class TransactionTest {
@Test
public void testTransaction(){
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao = (PersonDao)context.getBean("personDao");
personDao.savePerson();
}
}
代码解析
1.配置目标类与切面类的bean
2.开始配置 <aop:config>
<aop:config>
2.1、我们先配置后切入点 <aop:pointcut >
<aop:pointcut >
- 切入点中我认为最重要的就是配置切入点表达式的配置,最后在切入点中配置id,目的是让在切面中的各种通知里面使用
2.2、切面的配置 在配置切面时,有一个目标类的配置,就是将ref=“”指向切面的bean id 然后在切面中配置各种通知
2.2.1、前置通知
<aop:before method="beginTransaction" pointcut-ref="perform" />
2.2.2、后置通知
<aop:after-returning method="commit" pointcut-ref="perform" />
- 后置通知是after-returning,我的理解是后置通知是在目标方法执行之后执行的,它可以接受目标方法的返回值,所以他是以after-returning命名,这个返回值的配置在后面的比及中解释。
2.2.3、最终通知、异常通知、环绕通知在后面解释
原理
-
1、当spring容器启动的时候,加载两个bean,对两个bean进行实例化。
2、当spring容器对配置文件解析到
<aop:config>
的时候 。
3、把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean。
4、如果匹配成功,则为该bean创建代理对象。
5、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象 如果没有代理对象,则返回对象本身。
小结
这就是小编对SpringAop的简单理解与介绍,不过在有的实际开发中,有的使用基于注解的Spring AOP的配置及使用,那样的方式将Spring的配置文件“解脱了不少”,好了,就总结到这吧。