发表于: 2018-02-07 23:20:26
1 737
完成
1.统计访问DB时间,Controller处理时间,这个需要用到SpringAOP知识
什么是AOP——Aspect Orient Programming
面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单独处理。比如事务、日志和安全等。这个简单来说就是可以在一段程序之前或者之后做一些事。
为什么用AOP:你一开始只想写个功能A,B,C,后来,客户提出,你要进行登录验证,于是你在三段代码里加上了这个功能,后来,客户又说你要做日志记录,你又加上了这个功能。
但是需求是永远会变的,你的ABC随着时间的进行,可能多出了越来越多的无关的代码或者函数调用,这样显然不好。如果可以,你写一段代码,系统可以“自动”再需要的地方调用它——那么AOP就是为了满足这样的需求,常常用来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等等
不过AOP和IOC并不是spring中特有的,只是spring把他们应用的更灵活方便
在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
这里有很通俗的解释(https://segmentfault.com/a/1190000007469968)
用注解式跑了一个demo(其实也可以用xml式跑)
AnnotationTest类
package com.wlj.aop2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component("annotationTest")
@Aspect
public class AnnotationTest {
//定义切点
@Pointcut("execution(* *.saying(..))")
public void sayings() {
}
@Before("sayings()")
public void sayHello() {
System.out.println("注解类型前置通知");
}
//后置通知
@After("sayings()")
public void sayGoodbey() {
System.out.println("注解类型后置通知");
}
//环绕通知。注意要有ProceedingJoinPoint参数传入。
@Around("sayings()")
public void sayAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("注解类型环绕通知..环绕前");
pjp.proceed();//执行方法
System.out.println("注解类型环绕通知..环绕后");
}
}
BraveKnight类
package com.wlj.aop2;
import org.springframework.stereotype.Component;
@Component("knight")
public class BraveKnight {
public void saying(){
System.out.println("我是骑士..(切点方法)");
}
spring配置文件里加上
<context:component-scan base-package="com.wlj.aop2"/>
<!-- 开启aop注解方式,此步骤s不能少,这样java类中的aop注解才会生效 -->
<aop:aspectj-autoproxy/>
<!--注意:我们不仅仅要引入Aop的名称空间,还要在xsi:schemaLocation中加入aop的xsd文件 ,缺一不可-->
<!--否则会报错:通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明。-->
测试类
@Test
public void aop2() {
ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml");
BraveKnight br = (BraveKnight) ac.getBean("knight");
br.saying();
}
结果(截图发不出来)
注解类型环绕通知..环绕前
注解类型前置通知
我是骑士..(切点方法)
注解类型环绕通知..环绕后
注解类型后置通知
接下来的是任务要求的demo(这里参考了于师兄的日报,自己弄了很久没有实现)
package com.wlj.aop5;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogAdvice {
private static Logger loggerAdvice = Logger.getLogger(LogAdvice.class);
public Object around(ProceedingJoinPoint pip) throws Throwable {
//获取组件类名
String className = pip.getTarget().getClass().getName();
//获取调用方法名
String method = pip.getSignature().getName();
//取得数据库连接前时间
long begin = System.currentTimeMillis();
//当前系统时间
String date = new SimpleDateFormat("yyyy-MM-dd:mm:ss").format(new Date());
Object obj = pip.proceed();
//取得数据库连接后时间
long end = System.currentTimeMillis();
//数据库响应时间
int sqlTime = (int) (end - begin);
String msg = date + ",执行了" + className + "." + method + "()";
loggerAdvice.warn(msg + "\t数据库响应时间: " + sqlTime);
return obj;
}
}
spring配置文件加入
<bean id="LogAdvice" class="com.wlj.aop5.LogAdvice"/>
<aop:config>
<aop:pointcut id="pct" expression="execution(* com.wlj.service.*Impl.*(..))"/>
<aop:aspect id="myAspect" ref="LogAdvice">
<aop:around method="around" pointcut-ref="pct"/>
</aop:aspect></aop:config>
结果
问题
aop还要加深理解
收获
学了aop,面向切面编程
计划
把剩下的脚本写好,学自动部署
评论