发表于: 2018-01-15 05:52:13
2 597
今天完成的事情:
为了完成resin日志统计访问DB时间,Controller处理时间
学习springaop的知识
首先学习使用原生的Java的动态代理实现一个aop的demo
虽然跟着教程写出来了,知道可以实现AOP的功能,但是对动态代理本事怎么实现还是不太理解。
然后学习使用spring 结合 AspectJ实现AOP
今天了解注解方式比较多,xml文件的方式大概看了下。
要说明的是:如果在spring配置文件中的context:component-scan不扫描Controller层,那么在spring配置文件中的<aop:aspectj-autoproxy/> 不会切入到Controller层。
同理,如果在springMVC配置文件中的context:component-scan不扫描Controller以外的层,springMVC配置文件中的<aop:aspectj-autoproxy/>也不会切入到Controller以外的层。
所以要把一个Advice同时切入Service层和Controller层,需要在在spring配置文件、springMVC配置文件中都添加aop的配置。
查看resin日志统计访问DB时间,Controller处理时间
1 添加jar包
指定版本
<aspectj.version>1.8.13</aspectj.version>
引入
<!-- AOP的包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
2 开启注解
spring配置文件applicationContext.xml,负责切入Service层
<!-- 配置 AspectJ,因为springMVC的bean扫描早于spring的bean扫描
Controller层先创建完bean,这里的AOP后创建,所以在这里配置会出现
Controller层无法切入的问题,解决办法,springMVC配置里也添加-->
<!-- 同样这样的情况也存在于数据库事务中, 如果Service的Bean扫描配置在
spring-mvc.xml中, 而数据库事务管理器配置在application.xml中, 会导
致数据库事务失效, 原理一样 -->
<aop:aspectj-autoproxy/>
<aop:config>
<aop:pointcut id="servicePointCut" expression="execution(* com.bpzj.web.service..*(..))"/>
<aop:aspect id="serviceAspect" ref="logAdvice">
<aop:around method="aroundLog" pointcut-ref="servicePointCut"/>
</aop:aspect>
</aop:config>
注意学习表达式的一个固定写法:
<!-- 切入点表达式 -->
<!-- service..*(..) 第一个双点表示包括service包下的子包,*表示所有方法,括号中的双点表示任意参数 -->
springmvc配置文件,负责切入Controller层
<!-- 配置 AspectJ,要放到SpringMVC中,否则Controller层无法切入 -->
<aop:aspectj-autoproxy/>
<aop:config>
<aop:pointcut id="controllerPointCut" expression="execution(* com.bpzj.web.controller..*(..))"/>
<aop:aspect id="controllerAspect" ref="logAdvice">
<aop:around method="aroundLog" pointcut-ref="controllerPointCut"/>
</aop:aspect>
</aop:config>
3 编辑切面类
@Aspect
@Component
public class LogAdvice {
public static Logger loggerAdvice = Logger.getLogger(LogAdvice.class);
// 只切入Service层和Controller层,不切入DAO和Domain,所以改用xml配置
// @Around("execution(* com.bpzj.web..*(..))")
public Object aroundLog(ProceedingJoinPoint pjp) {
Object result = null;
// 获取 切入方法 的名称
String methodName = pjp.getSignature().getName();
// 获取 切入类 的名称
String className = pjp.getTarget().getClass().getName();
try {
// 用在最后相减,获得一个时间差,认为是数据库操作的时间
long begin = System.currentTimeMillis();
// 执行切入方法
result = pjp.proceed();
// 计算操作时间并记录到日志
long end = System.currentTimeMillis();
int ResponseTime = (int) (end - begin);
String msg = " Weaving\t" + className + "." + methodName + "() ";
loggerAdvice.info(msg + "\t response time is: " + ResponseTime +"ms");
} catch (Throwable e) {
// 异常通知
loggerAdvice.error(e);
throw new RuntimeException(e);
}
return result;
}
}
4 完善并更改为xml形式
刚开始全部用的注解,后来出现问题:
使用注解只能 @Around("execution(* com.bpzj.web..*(..))")
或者只切入Controller层,或者只切入Service层,却没办法只切入Controller层和Service层这两层。
所以改用xml配置:在spring配置中切入service层,在SpringMVC中切入Controller层。
5 部署到Resin并,查看日志,统计响应时间
明天计划的事情:
任务4、以及前边复习。
遇到的问题:
刚开始只在spring配置文件中开启了AOP注解,debug时,controller层没有被切入。
百度出来,spring和springMVC的ApplicationContext是分开的,加载bean也是分开的,所以要同时配置。
收获:
初步学习AOP
评论