AOP和Spring事务处理
【IT168 技术文档】
一.为什么要用框架和模式
1.为什么要用模式?
因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的非常好的办法。
2.为什么要用框架?
因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事物处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。
总之:就是让开发更简单,让我们成功
二. AOP
1. AOP是什么?
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
2. 切面意义何在?
就可以在这层切面上进行统一的集中式权限管理。而业务逻辑组件则无需关心权限方面的问题。也就是说,通过切面,我们可以将系统中各个不同层次上的问题隔离开来,实现统一集约式处理。各切面只需集中于自己领域内的逻辑实现。这一方面使得开发逻辑更加清晰,专业化分工更加易于进行;另一方面,由于切面的隔离,降低了耦合性,我们就可以在不同的应用中将各个切面组合使用,从而使得代码可重用性大大增强。
3. AOP应用范围
- Authentication 权限
- Caching 缓存
- Context passing 内容传递
- Error handling 错误处理
- Lazy loading 懒加载
- Debugging 调试
- logging, tracing, profiling and monitoring 记录跟踪 优化 校准
- Performance optimization 性能优化
- Persistence 持久化
- Resource pooling 资源池
- Synchronization 同步
- Transactions 事务
三.Spring事务处理
1.Spring事务管理能给我们带来什么?
对于传统的基于特定事务资源的事务处理而言(如基于JDBC 的数据库访问),Spring并不会对其产生什么影响,我们照样可以成功编写并运行这样的代码。同时,Spring还提供了一些辅助类可供我们选择使用,这些辅助类简化了传统的数据库操作流程,在一定程度上节省了工作量,提高了编码效率。
对于依赖容器的参数化事务管理而言,Spring则表现出了极大的价值。Spring本身也是一个容器,只是相对EJB容器而言,Spring显得更为轻便小巧。我们无需付出其他方面的代价,即可通过Spring实现基于容器的事务管理(本质上来讲,Spring的事务管理是基于动态AOP)。
2. Hibernate in Spring
applicationContext.xml
</bean>
<bean id="baseTxProxy" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"> <ref local=" userManagerTarget " />
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userManagerTarget" class="org.mzone.service.impl.UserManagerImpl">
<property name="userDAO"><ref local="userDAO"/></property>
<property name="articleDao"><ref local="articleDAO"/></property>
</bean>
UserDAO.java ArticleDAO.java
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO ...{
public void saveUser(Tuser user) ...{
getHibernateTemplate().saveOrUpdate(user);
}
}
![]()
public class ArticleDAOImpl extends HibernateDaoSupport implements ArticleDAO ...{
public void saveArticle(Article article) ...{
getHibernateTemplate().saveOrUpdate(article);
![]()
}
![]()
}
HibernateDaoSupport
实现了HibernateTemplate和SessionFactory实例的关联。HibernateTemplate对Hibernate Session操作进行了封装,而HibernateTemplate.execute方法则是一封装机制的核心,感兴趣可以研究一下其实现机制。
借助HibernateTemplate我们可以脱离每次数据操作必须首先获得Session实例、启动事务、提交/回滚事务以及烦杂的try/catch/finally的繁琐操作。从而获得以上代码中精干集中的逻辑呈现效果。
org.mzone.service.impl.UserManagerImpl
public class UserManagerImpl implements UserManager ...{
private UserDAO userDao;
private ArticleDAO articleDao;
public void saveUserAndArticle(Tuser user, Article article) ...{
userDao.saveUser(user);
articleDao.saveArticle(article);
}
}
测试代码
InputStream is = new FileInputStream("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
UserManager userManager = (UserManager )factory.getBean(" baseTxProxy ");
![]()
user = new Tuser();
article = new Article();
user.setUsername("hellboys_topic 1");
user.setPassword("12345678_topic 1");
article.setTitle("hellboys_topic 1");
article.setContent("hellboys_topic 1");
![]()
userManager.saveUserAndArticle(user,article);
注意问题
UserManager userManager = (UserManager )factory.getBean(" baseTxProxy ");
UserManager userManager = (UserManagerImpl) ctx.getBean("baseTxProxy");
java.lang.ClassCastException
原因在于Spring的AOP实现机制,前面曾经提及,Spring中的事务管理实际上是基于动态AOP机制实现,为了实现动态AOP,Spring在默认情况下会使用Java DynamicProxy,但是,Dynamic Proxy要求其代理的对象必须实现一个接口,该接口定义了准备进行代理的方法。而对于没有实现任何接口的Java Class,需要采用其他方式,Spring通过CGLib10实现这一功能。
CGLib可以在运行期对Class行为进行修改。由于其功能强大,性能出众,常常被作为Java Dynamic Proxy之外的动态Proxy模式的实现基础。在Spring、Hibernate中都用到了CGLib类库。
