AOP 即 Aspect Oriented Program面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
1.how2j案例:
日志切面 LoggerAspect:
public class LoggerAspect {
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("start log:" + joinPoint.getSignature().getName());
Object object = joinPoint.proceed();
System.out.println("end log:" + joinPoint.getSignature().getName());
return object;
}
}
JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象。ProceedingJoinPoint对象是JoinPoint的子接口。
加入切面后,TestSpring 代码没有发生任何变化。编织之后,业务方法运行之前和之后分别会打印日志。
2.教材11-6的案例,利用TransactionTemplate实现Spring编程式事务管理
TransactionExample定义添加数据的方法,在方法中执行两次添加数据库操作并用事务保护操作
public void transactionOperation() {
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Connection conn = DataSourceUtils.getConnection(dataSource);//获得数据库连接
try {
Statement stmt = conn.createStatement();
//执行两次添加方法
stmt.execute("insert into tb_user(name,age,sex) values('小强','26','男')");
int a=0;//制造异常测试事务是否配置成功
a=9/a;
stmt.execute("insert into tb_user(name,age,sex) values('小红','22','女')");
System.out.println("操作执行成功!");
} catch (Exception e) {
transactionManager.rollback(status);//事务回滚
System.out.println("操作执行失败,事务回滚!");
System.out.println("原因:"+e.getMessage());
}
return null;
}
});
}
插入数据操作成功执行:
在执行两次添加操作的语句之间添加代码制造人为异常,第一条操作语句成功执行后,第二条操作语句因为程序的异常无法执行。事务回滚,则事务配置成功。 程序执行后,tb_user数据表中没有插入数据。
3.教材11-7的案例,利用TransactionProxyFactoryBean实现Spring声明式事务管理。
<!-- 定义TransactionProxy -->
<bean id="transactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="target">
<bean id="addDAO" class="com.mr.dao.AddDAO">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
</property>
<property name="proxyTargetClass" value="true" />
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
编程式事务:通过硬编码的方式使用spring中提供的事务相关的类来控制事务。
声明式事务:通过配置的方式,比如通过配置文件(xml)或者注解的方式,告诉spring,哪些方法需要spring帮忙管理事务,然后开发者只用关注业务代码,而事务的事情spring自动帮我们控制。比如注解的方式,只需在方法上面加一个@Transaction
注解,那么方法执行之前spring会自动开启一个事务,方法执行完毕之后,会自动提交或者回滚事务,而方法内部没有任何事务相关代码。在一定程度上节省工作量,提高编码效率。