一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

SpringAOP的一个使用例子

时间:2026-09-03 20:03:48 编辑:袖梨 来源:一聚教程网

SpringAOP的一个使用例子的重点在于把前置条件、操作顺序和容易误判的地方分清楚。

0.前言

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

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.创建小组 (首先创建小组, 然后小组创建动态 , 最后添加关联)

2.记录用户和小组关联(先添加关联,再记录用户加入动态,删除用户申请消息)

类似这样的情况,程序中大概还有几个地方。

3.功能改进

今天项目上线了,功能一切正常,下午在看代码的时候,突然想到Spring有AOP的功能,我可以考虑一下AOP去实现这个功能。

@黄勇 博客的 《AOP那些事儿》http://my.oschina.net/huangyong/blog/161402

找到了Spring AOP的功能实现 12.Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)

在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

热门栏目