锁定老帖子 主题:Spring AOP实际项目中使用案例
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-07-12
AOP有三种织入切面的方法: 其一是编译期织入,这要求使用特殊的Java编译器,AspectJ是其中的代表者; 其二是类装载期织入,而这要求使用特殊的类装载器,AspectJ和AspectWerkz是其中的代表者; 其三为动态代理织入,在运行期为目标类添加增强生成子类的方式,Spring AOP采用动态代理织入切面。 Spring AOP使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供基于接口的代理,不支持类的代理。
AOP概念到处都在传,之前以为自己了解了,无非就是应用在日志、事务、权限方面的面向切面编程思想的一种架构或者设计模式罢了,今天在迁移一个项目的时候,发现了AOP的妙处。
实际场景描述,可以说基本每个表结构或者说数据对象都需要createuser,createdate,updateuser,updatedate,创建者,创建时间,修改者,修改时间,如果每次都要自己手动写,在每个dao的add和update方法中复制粘贴,很容易出错,而且工作量比较大的,不能保证完全正确。这个时候我们就可以使用AOP思想,来处理解决该问题。
package com.xxx.util; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; import com.xxx.domain.BaseDomain; @Aspect @Repository("maintainAspect") public class MaintainAspect { final static Logger logger = LoggerFactory .getLogger(MaintainAspect .class); //扫描路径访问规则,对所有add**的方法进行代理写入 //所有需要代理写入的方法必须继承BaseDomain,然后强制写入相关用户信息 @Before("execution(public * com.xxx.dao.impl.*.add*(..)) && args(baseDomain,..)") public void appendCreateInfo(BaseDomain baseDomain) throws Exception { if (baseDomain instanceof Session || baseDomain instanceof SystemLog) { return; } Session session = ThreadVariable.getSession(); if (session == null || session.getUserName() == null) { logger.error("系统尝试在无登陆的情况下添加[{}]对象", baseDomain.getClass() .getName()); throw new Exception("Session不存在,系统不能正常工作!"); } baseDomain.setCreateDate(session.getAccessTime()); baseDomain.setCreateUser(session.getUserName()); } @Before("execution(public * com.tianque.locationtalk.dao.impl.*.update*(..)) && args(baseDomain,..)") public void appendUPdateInfo(BaseDomain baseDomain) throws Exception { if (baseDomain instanceof Session || baseDomain instanceof SystemLog) { return; } Session session = ThreadVariable.getSession(); if (session == null || session.getUserName() == null) { logger.error("系统尝试在无登陆的情况下更新[{}]对象,对象ID为[{}]", baseDomain .getClass().getName(), baseDomain.getId()); throw new Exception("Session不存在,系统不能正常工作!"); } baseDomain.setUpdateDate(session.getAccessTime()); baseDomain.setUpdateUser(session.getUserName()); } } 配置环境方面不需要任何更改,也不需要影响之前任何代码,即可实现对相关的数据对象自动添加createuser,createdate,updateuser,updatedate。
AOP非常good,这种没有侵害的改造让人非常赏心悦目。很多时候都是人云亦云,以为AOP只能处理事务、日志等东西,实际上AOP远不止的,我们可以让我们的代码变得更加有质量的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-07-14
跟处理日志有本质区别么?
|
|
返回顶楼 | |
发表时间:2011-07-14
你这种方式一定前期要有规范文档,方法名命名全统一,比如create开头,update开头,如有人喜欢add,或者save等等,你的aop就需要判断很多种情况
|
|
返回顶楼 | |
发表时间:2011-07-14
最好有个全局的继承体系结构 方便类型的判断
|
|
返回顶楼 | |
发表时间:2011-07-14
AOP用好了可以造福整个系统,前提是要有合理的规化及文档描述,否则对整个系统的调试排错有一定的阻碍作用
|
|
返回顶楼 | |
发表时间:2011-07-14
没什么 反射而已!
|
|
返回顶楼 | |
发表时间:2011-07-14
就是基本的domain类一些域默认的赋值问题,不是很明白为什么要用AOP来解决这个问题
|
|
返回顶楼 | |
发表时间:2011-07-14
最后修改:2011-07-14
大型系统是不能这么做的,宁可多写一点代码也不能取代整个系统的某个操作;可以在各个子系统中尝试这样的配置方式;或者尝试封装baseDao这样的一个基类,每个类继承它也行
|
|
返回顶楼 | |
发表时间:2011-07-14
很难确定一个足够完善的pointcut,能匹配可能的情况,而且出错时很难查找错误!
|
|
返回顶楼 | |
发表时间:2011-07-15
比较建议对应的pointcut,是通过xml进行配置。你的pointcut会随着具体的业务场景,package名不同而变化,但你的advise业务是稳定的,没必要将两者捆绑
|
|
返回顶楼 | |