Spring AOP的一个使用例子

0.前言

    学习Spring,确定会了解IOC和AOP的思想,除了Spring的基本使用,本身在实际应用中,还真没特地使用过AOP的功能。最近有一个项目使用到了Spring,因为以前也没有Spring的实际工做经验,加上项目比较着急,因此有不少细节不完善的地方。下面介绍AOP使用的一个例子,有不对或者更好的解决方法,欢迎指正。 java

1.功能需求

    项目是一个学习小组,用户能够建立小组,加入小组,离开小组,以及其它一系列功能。在小组首页里有一个小组动态。这就须要咱们在程序中,处理用户基本操做之外,还要保存相应的小组动态。 服务器

2.基本实现

    首先想到的就是写一个公共的方法,在须要的地方进行调用。由于里面有两个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

3.功能改进

    今天项目上线了,功能一切正常,下午在看代码的时候,忽然想到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方法调用,测试一切正常... 

4.总结

    本身在项目中,也是先实现基本功能的增删改查,而后再不断完善功能,好比小组动态就是后来加入的,固然须要修改原来的程序。

    若是咱们使用AOP的方法,那么原有程序咱们就能够不用修改了,只用找到切入点,根据须要在切入点的先后加上相应的操做。并且维护起来也比较容易,好比咱们想去掉某个类型的日志记录,或者加入新的动态记录,都不用再去修改源代码。

   固然能够参考@黄勇 博客的 《AOP那些事儿》http://my.oschina.net/huangyong/blog/161402,采用第十三种,经过自定义注解的方式进行实现,这样就不用写多个方法了....

  注:使用Spring+Aspectj 的AOP可能须要Cglib 的jar   

相关文章
相关标签/搜索