日期:2014-05-17 浏览次数:21024 次
注释形式的AOP编程,便利的实现了运行时对类及其方法的监控及干预,使生活变得更美好。 —— 《Seraph川上曰》
?
环境 :系统开发过程中,我们都曾实现过将系统元数据或字典表添加到缓存中,以便程序调用,减少数据库访问IO。
问题 :在用户通过前端页面更新系统字典表时,需手工刷新系统缓存,操作很不友好。
解决方案 :监听持久层DAO方法的调用,对于目标表的insert,update,delete操作进行相应的系统缓存更新。
?
示例环境 :Spring2.5 + iBatis + AspectJ
参考书目 :Spring 2.5 Aspect-Oriented Programming
?
?
Spring AOP自动代理的XML配置
?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <aop:aspectj-autoproxy/> </beans>?
被监测类的代码:
?
public interface ScDbInfoDAO { BigDecimal insert(ScDbInfo record); int updateByPrimaryKey(ScDbInfo record); int updateByPrimaryKeySelective(ScDbInfo record); List selectByExample(ScDbInfoExample example, String orderByClause); List selectByExample(ScDbInfoExample example); ScDbInfo selectByPrimaryKey(BigDecimal dbId); int deleteByExample(ScDbInfoExample example); int deleteByPrimaryKey(BigDecimal dbId); int selectCountByExample(ScDbInfoExample example); }
?
然后是AspectJ实现:
?
import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Service; /** * @author seraph * */ @Service @Aspect public class JdbcSourceInterceptor { private static final Logger log = Logger.getLogger(JdbcSourceInterceptor.class); @AfterReturning(value="execution(* com.longtop.data.switching.db.dao.ScDbInfoDAO.*(..))", argNames="rtv", returning="rtv") public void afterInsertMethod(JoinPoint jp, Object rtv) throws Throwable { Signature signature = jp.getSignature(); log.debug("DeclaringType:" + signature.getDeclaringType()); log.debug("DeclaringTypeName:" + signature.getDeclaringTypeName()); log.debug("Modifiers:" + signature.getModifiers()); log.debug("Name:" + signature.getName()); log.debug("LongString:" + signature.toLongString()); log.debug("ShortString:" + signature.toShortString()); for (int i = 0; i < jp.getArgs().length; i++) { Object arg = jp.getArgs()[i]; if(null != arg) { log.debug("Args:" + arg.toString()); } } log.debug("Return:" + rtv); } }
?
运行时的监测日志:
?
JdbcSourceInterceptor - DeclaringType:class dao.impl.ScDbInfoDAOImpl JdbcSourceInterceptor - DeclaringTypeName:dao.impl.ScDbInfoDAOImpl JdbcSourceInterceptor - Modifiers:1 JdbcSourceInterceptor - Name:selectByPrimaryKey JdbcSourceInterceptor - LongString:ScDbInfoDAOImpl.selectByPrimaryKey(BigDecimal) JdbcSourceInt