spring 之 AOP 理解

AOP 面向切面编程,个人认为也可以理解为抽取各个业务模块中所共有的部分,放在一个 springXXX.xml 的文件中由spring框架进行统一的管理,把业务逻辑和其他的控制模块分离,比如银行里 ATM 的查询、取现和转账的业务都需要进行用户信息验证,如下图:


这是 OOP(Object Oriented Programming) 的管理模式,可以看出这三个模块都有一个公共的部分:用户信息验证,因此,可以把这一部分单独抽取出来放在一个地方进行统一的管理,这就是 aop 的思想。我们可以发挥一下想象,假如有100或者更多个这样的模块,把它们放在一起,而并非一排,这样抽取的公共部分就相当于一个切面,这个切面的具体含义就是告诉 spring 应该在哪里做什么事情,比如这个银行系统,切面的含义就是告诉spring 在取现、查询和转账之前,都需要进行 “用户信息验证”,切面抽出来之后由谁来告诉spring做这个事情呢?那就是 advice(通知)了,看下面这个具体的实例:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 这个 trans 配置完全可以在 applicationContex-service 里面配置,
	只是为了看着更清楚,单独拿出来配置
 -->
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 数据源 -->
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 传播行为 -->
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="create*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!-- 切面 -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice"
			pointcut="execution(* com.maxiao.service.*.*(..))" />
	</aop:config>
</beans>

这是一个常见的由 spring 来管理实务的配置,我们现在已经知道实务管理这个模块可以作为一个切面,也就是说切面现在已经有了,我们要拿这个切面去切谁呢?总归要有个切的地方吧,因此在 <aop:config> 标签中配置了切面所要切的地方,也就是 com.maxiao.service 这个包下的所有的类的所有方法,也就是告诉了 spring 要到这里去找具体要切的对象,但是并没有告诉 spring 要切谁,因此在 advice (通知)里面配置了具体切的对象,即:在这个包里面的所有类的所有方法中,只要方法名称里包含 insert,add,create,delete,update...等这些名称,就由 advice 通知事物管理器 DataSourceTransactionManager为该方法添加一个事物:


注释:每个蓝色的长方体代表一个方法

这些方法可能来自service包下面的不同的类,但是这并不重要,只要方法名称中有这样的字眼,我就要“把你切了”

其实事务控制只是 spring aop 应用的一个方面,还有其他很多的方面比如日志管理等,我认为更重要的是要能理解 aop 的这种思想,即:把项目模块中公共的部分抽取出来由 spring 来进行统一的管理,实现和实际的业务解耦,简化代码,便于维护等目的

猜你喜欢

转载自blog.csdn.net/maxiao1204/article/details/80882538