基于SSH2框架AspectJ的登录登出日志实现
前段时间帮朋友搞了个小项目,也是在网上参考了别人博客后自己运用AspectJ AOP切面实现登录登出日志的功能。今天拿出来和大家分享下。
AOP切面是一个非常不错的特性,为我们带来了一种新的编程方式,对代码的无侵入性是它最大的特点。平时我们用到的Struts2拦截器就是AOP的一个典型运用。从Spring的低版本开始就能够实现切面功能,但是非常麻烦,不过当Spring升级到2.0之后,这一情况就彻底改变了。运用JDK 5.0支持的注解特性,大大方便了我们的开发。在本篇中,我将以AspectJ注解方式实现AOP的切面功能。
在这里我还是假设一下,你已经对Spring AOP有一个基本了解,至少知道AOP的基本概念,比如:切入点,通知,切入表达式,横切逻辑等等内容。那么只需要在之前的基础上做下小小的改变,就可以使用AspectJ实现日志的登录登出功能。
增加日志表
记录日志信息当然需要日志表了,我们在数据库中增加一个log表。
Create table 'log'( 'id' int(11) not null; 'name' varchar(20) default null; 'method' varchar(20) default null; 'time' timestamp default null; primary key('id') )engine=InnoDB default charset=uft8 /** * 使用AspectJ实现登录登出日志AOP * @author wuxw920 */ @Aspect public class LogAspect{ @Autowired @Qualifier("hibernateDao") private LogDAO logDao; @After("execution(* com.wuxw920.ssh.LoginAction.login(..))") public void afterLoginLog(JoinPoint joinPoint) throws Throwable{ User user = (User)ServletActionContext.getRequest().getSesion().getAttribute("user"); if(user != null){ saveLog(user,joinPoint);//保存登入日志 } } @Before("execution(* com.wuxw920.ssh.LoginAction.logout(..))") public void beforeLogoutLog(JoinPoint joinPoint) throws Throwable{ User user = (User)ServletActionContext.getRequest().getSesion().getAttribute("user"); if(user != null){ saveLog(user,joinPoint);//保存登出日志 } } private void saveLog(User user , JoinPoint joinPoint){ Log log = new Log(); log.setName(user.getName()); log.setMethod(joinPoint.getSignature().getName());//切入方法 log.setTime(new Timestamp(System.currentTimeMillis()));时间 logDao.save(log); } }<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />,作用是确保Spring的自动装配策略总是被考虑。默认为false,如果不将它改为true,则在使用CGLib代理Action类后,使用@Autowired注入的service类将会为null,那么这些目标方法中与数据库交互的逻辑都不能执行,所以一定要将它改为true。
<aop:aspectj-autoproxy proxy-target-/>声明,为Spring容器中那些匹配@AspectJ切面的Bean创建代理,其中的proxy-target-表示使用CGLib动态代理技术织入增强,不过只声明还不行,还得织入,把编写好的切面类完整路径添加到配置文件中,这样才能发挥切面的功能。