学习Spring,确定会了解IOC和AOP的思想,除了Spring的基本使用,本身在实际应用中,还真没特地使用过AOP的功能。最近有一个项目使用到了Spring,因为以前也没有Spring的实际工做经验,加上项目比较着急,因此有不少细节不完善的地方。下面介绍AOP使用的一个例子,有不对或者更好的解决方法,欢迎指正。 java
项目是一个学习小组,用户能够建立小组,加入小组,离开小组,以及其它一系列功能。在小组首页里有一个小组动态。这就须要咱们在程序中,处理用户基本操做之外,还要保存相应的小组动态。 服务器
首先想到的就是写一个公共的方法,在须要的地方进行调用。由于里面有两个DAO操做,因此封装成了一个service方法。在不一样的service中注入service调用这个方法。这个方法大概须要几个参数,记录小组id,用户id,以及动态的type 学习
public void addTeamNewsLog(long team_id,long user_id,int type){ long ref = studyTeamInfoDAO.getSeqAllRef(); StudyTeamNews news =new StudyTeamNews(); news.setRef(new BigDecimal(ref)); news.setTeamId(new BigDecimal(team_id)); news.setUserId(new BigDecimal(user_id)); news.setType((short) type); studyTeamNewsDAO.insertSelective(news); }
好比 测试
1.建立小组 (首先建立小组, 而后小组建立动态 , 最后添加关联) spa
2.记录用户和小组关联(先添加关联,再记录用户加入动态,删除用户申请消息) .net
相似这样的状况,程序中大概还有几个地方。 debug
今天项目上线了,功能一切正常,下午在看代码的时候,忽然想到Spring有AOP的功能,我能够考虑一下AOP去实现这个功能。 日志
@黄勇 博客的 《AOP那些事儿》http://my.oschina.net/huangyong/blog/161402 code
找到了Spring AOP的功能实现 12. Spring + AspectJ(基于注解:经过 AspectJ execution 表达式拦截方法) xml
在Spring的配置文件中加入
<aop:aspectj-autoproxy proxy-target-class="true"/>
在项目下新建一个package,建立了一个Aspect类,加入一个新方法
1.首先经过AspectJ execution表达式 写拦截的方法 (Intellij IDEA有智能提示)
2.在after()方法打一个断点
@Around("execution(* com.etiantian.studyteam.dao.StudyTeamInfoDAO.insert(..))") public Object addTeamOk(ProceedingJoinPoint pjp)throws Throwable{ Object result = pjp.proceed(); after(); return result; }
重启服务器....建立战队....OK,进入断点了,说明咱们的AOP功能起做用了,下面我就能够记录动态了
3.在pjp.proceed();方法打一个断点,而后debug进去 看看pjp中有什么东西,发现有方法名,有参数,再上网查一下ProceedingJoinPoint这个类,能够经过getArgs 得到切入方法的参数。
4.根据本身的功能须要,修改方法
@Around("execution(* com.etiantian.studyteam.service.facede.StudyTeamJUserService.saveStudyTeamJUser(..))") public Object addTeamUser(ProceedingJoinPoint pjp)throws Throwable { long team_id=Long.parseLong(pjp.getArgs()[0].toString()); long user_id=Long.parseLong(pjp.getArgs()[1].toString()); Object result = pjp.proceed(); addStudyTeamLog(team_id, user_id, StudyTeamBaseAction.ADD_TEAM_USER); return result; } @Around("execution(* com.etiantian.studyteam.dao.StudyTeamInfoDAO.insert(..))") public Object addTeamOk(ProceedingJoinPoint pjp)throws Throwable{ Object result = pjp.proceed(); StudyTeamInfo st =(StudyTeamInfo)pjp.getArgs()[0]; addStudyTeamLog(st.getTeamId().longValue(), st.getcUserId().longValue(), StudyTeamBaseAction.ADD_TEAM_OK); return result; } private void addStudyTeamLog(long team_id,long user_id,int type){ studyTeamInfoService.addTeamNewsLog(team_id,user_id,type); }
5.注释掉原有service中的全部 addTeamNewsLog方法调用,测试一切正常...
本身在项目中,也是先实现基本功能的增删改查,而后再不断完善功能,好比小组动态就是后来加入的,固然须要修改原来的程序。
若是咱们使用AOP的方法,那么原有程序咱们就能够不用修改了,只用找到切入点,根据须要在切入点的先后加上相应的操做。并且维护起来也比较容易,好比咱们想去掉某个类型的日志记录,或者加入新的动态记录,都不用再去修改源代码。
固然能够参考@黄勇 博客的 《AOP那些事儿》http://my.oschina.net/huangyong/blog/161402,采用第十三种,经过自定义注解的方式进行实现,这样就不用写多个方法了....
注:使用Spring+Aspectj 的AOP可能须要Cglib 的jar