Spring AOP
AOP 的全称为Aspect Oriented Programming,译为面向方面编程,针对具体业务领域、业务逻辑。AOP目的是 将复杂逻辑进行分离,抽取共性,让各部分实现实现的功能更为专一。如,Spring AOP思想实现的经典案例“事务 管理”,每个访问数据库的业务类都有可能用到事务控制,将其事务管理代码从具体类中抽取出来,放到一个单独的 地方处理,这样大大简化了具体业务类的代码。
Aspect(方面):我们所关注的,可以被抽取的业务逻辑,如图中的“事务管理”。
JoinPoint(连接点):程序在执行过程中明确的点,如图中execute()方法。
Advice(通知):在特定的连接点执行的动作。如在执行execute()方法前的预处理, 在执行完execute() 方法后的后处理。
PointCut(切入点):如图中在客户调用execute()时才产生图中所示动作,还也可以 设定产生同样动作的方法,如save(),update(),甚至申明成“save.*”,这些申明的 集合就称之为切入点。
TargetObject(目标对象):包含连接点的对象,也称为被代理的对象。如图中的“业务组件”
理解完概念,接下来看实际例子:
在Spring IOC章节中,DataAccessor.java的Save方法中是 未经事务管理分离的实现,我们采用AOP实现后,期望将实现代码变成如下:
例 2.1. DataAccessor.java
public void save(String sql)
{
Statement s = getStatement();
int rows = s.executeUpdate(sql);
}
多么美妙的想法,看实现方法:
1、 AOP中的“方面”已经明确,即“事务管理”,通常用拦截器来实现其功能。我们可以通过实现 AOP联盟提供的通用AOP接口MethodInterceptor自定义拦截器。本例借助Spring中提供的 org.springframework.jdbc.datasource.DataSourceTransactionManager事务管理 类实现。
2、”目标类“我们也已经明确,即DataAccessor.java。
3、定义切入点,该例中我们期望在执行save方法时做事务管理控制。
4、在SpringConfig.xml文件中进行相关配置
例 2.2. SpringConfig.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>org.gjt.mm.mysql.Driver</value></property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=GBK</value>
</property>
<property name="username"><value>root</value></property>
<property name="password"><value></value></property>
</bean>
<bean id="dataAccessor" class="DataAccessor">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> (1)
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="dataAccessorProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> (2)
<property name="transactionManager"> (3)
<ref bean="transactionManager" />
</property>
<property name="target"> (4)
<ref local="dataAccessor" />
</property>
<property name="transactionAttributes"> (5)
<props>
<prop key="save">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
经 过以上的配置,改动下DataAccessor.java类的实现,因为这里我们用的dataSource类为Spring提供的 org.apache.commons.dbcp.BasicDataSource,且我们可以通过JdbcTemplate执行相关数据库访问操作。
例 2.3. DataAccessor.java
public class DataAccessor
{
private DataSource dataSource;
public void setDataSource(DataSource dataSource)
{
this.dataSource = dataSource;
}
public void save()
{
JdbcTemplate template = new JdbcTemplate(this.dataSource);
template.update("insert into game (name) values ('test')");
}
}
save ()中代码完全是我们所期望完全样子,不用关系异常处理,不用关系事务管理,设想一下,如果项目 中有100百个这样的业务类,那能节省你不少敲这种重复代码的时间了,最重要的是我们让某个业务逻辑得 到集中处理,便于日后维护与扩展。 这就是借助AOP的好处。以后面对一个复杂的业务逻辑处理时,别忘了 想想是否能借助面向方面的思想去解决问题。