一直以来都知道Spring支持一种叫做面向切面编程(AOP)的东西,但是一直都没有自己尝试使用过. 直到最近为了Debug方法,记录使用时间猛然发现AOP正好适合使用在这个场景下.为了灵活的使用AOP,我选择了使用注解来作为标记,当某个特定的注解被使用的时候将会自动触发这个切面.
1.注解的编写
1
2
3
4
5
6
7
8
9
10
11
12
13
|
packageorg.jzbk.rssplus.aspect.annotation;
importjava.lang.annotation.*;
/**
* Created by Kotarou on 2017/1/11.
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public@interfaceTimed{
booleandisplayArgs()defaultfalse;
}
|
将注解设置为运行时RetentionPolicy.RUNTIME, 在编译时不会丢失这个注解信息.
设置注解主体为方法和类.
注解内部保存一个displayArgs的boolean变量,用于判断是否输出传入参数.
2. 编写AOP类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
packageorg.jzbk.rssplus.aspect;
importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.Signature;
importorg.aspectj.lang.annotation.Around;
importorg.aspectj.lang.annotation.Aspect;
importorg.aspectj.lang.annotation.Pointcut;
importorg.aspectj.lang.reflect.MethodSignature;
importorg.jzbk.rssplus.aspect.annotation.Timed;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.stereotype.Component;
importjava.lang.reflect.Method;
/**
* Created by Kotarou on 2017/1/11.
*/
@Aspect
@Component
publicclassTimedAOP{
finalprivateLogger logger=LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(org.jzbk.rssplus.aspect.annotation.Timed) ||
@target(org.jzbk.rssplus.aspect.annotation.Timed)")
publicvoidannotationProcessor(){
}
@Pointcut("execution(public * org.jzbk.rssplus..*.*(..))")
publicvoidpublicMethod(){
}
@Around(value="publicMethod() && annotationProcessor()")
publicObjectcount(ProceedingJoinPoint proceedingJoinPoint)throwsThrowable{
finalStringmethodName=proceedingJoinPoint.getSignature().getName();
LongstartTime=System.currentTimeMillis();
Objectresult=proceedingJoinPoint.proceed();
LongfinishTime=System.currentTimeMillis();
Signature signature=proceedingJoinPoint.getSignature();
String[]packageName=signature.getDeclaringTypeName().split("\\.");
StringBuilder stringBuilder=newStringBuilder();
for(inti=0;i<packageName.length;++i){
if(i<packageName.length-1){
stringBuilder.append(packageName[i].substring(0,1));
}else{
stringBuilder.append(packageName[i]);
}
stringBuilder.append(".");
}
logger.info("Executing: "+stringBuilder+signature.getName()+" took: "+(finishTime-startTime)+" ms");
Method method=((MethodSignature)proceedingJoinPoint.getSignature()).getMethod();
if(method.getDeclaringClass().isInterface()){
method=proceedingJoinPoint.getTarget().getClass().getDeclaredMethod(
methodName,method.getParameterTypes());
}
// 方法上的注解优先级比类上的注解高,可以覆盖类上注解的值
Timed timed=null;
if(method.isAnnotationPresent(Timed.class)){
//处理方法上的注解
timed=method.getAnnotation(Timed.class);
if(timed.displayArgs()){
logArgs(proceedingJoinPoint.getArgs());
}
}else{
//处理类上面的注解
Objecttarget=proceedingJoinPoint.getTarget();
if(target.getClass().isAnnotationPresent(Timed.class)){
timed=target.getClass().getAnnotation(Timed.class);
if(timed.displayArgs()){
logArgs(proceedingJoinPoint.getArgs());
}
}
}
returnresult;
}
privatevoidlogArgs(Object[]args){
StringBuilder stringBuilder=newStringBuilder();
for(inti=0;i<args.length;++i){
stringBuilder.append("[");
stringBuilder.append(i);
stringBuilder.append("]: ");
stringBuilder.append(args[i].toString());
if(i<args.length-1){
stringBuilder.append(", ");
}
}
if(!stringBuilder.toString().isEmpty())
logger.info("Argument List: "+stringBuilder);
else
logger.info("Argument List: Empty");
}
}
|
AOP的切入点为使用了Timed的方法或者类.
方法上面的注解优先级比类上面的高,可以在方法上使用注解来覆盖掉类上注解的值.
演示:
在类上面增加注解,并设置displayArgs为true
在某个方式上覆盖注解冰将displayArgs设置为false
运行tomcat,查看日志
结果和期望中的一样.
https://www.jzbk.org/archives/423.html
相关推荐
功能说明: 环境说明: 开发软件:VS 2017 (版本2017以上即可,不能低于2017) 数据库:SqlServer2008r2(数据库版本无限制,都可以导入) 开发模式:mvc。。。
labview程序代码参考学习使用,希望对你有所帮助。
大米外贸商城系统 简称damishop 完全开源版,只需做一种语言一键开启全球133中语言自动翻译功能,价格实现自动汇率转换,集成微信支付宝 paypal以及国外主流支付方式,自带文章博客系统。 软件架构 基于MVC+语言包模式,增加控制台,API导入产品方便对接其他系统(带json示例数据)。 使用要求 PHP7.4+ MYSQL5.6+ REDIS(可选) 安装方法 composer install 打开安装向导安装 http://您的域名/install 特色 1、缓存层增加时间与批量like删除 2、API产品导入方便对接其他系统 3、增加控制台命令行,命令行生成语言翻译包 4、后台一键开启自动翻译模式,支持全球133中语言,由于google代理翻译需要收费,这个功能需要付费。 5、可选购物车与ajax修改购物车产品 6、一键结算checkout 7、增加网站前台自定义路由 方便seo 更新日志 v3.9.7 集成鱼码支付接口,方便个人站长即使收款到账使用 v3.9.3 更新内容 1:增加ueditor与旧编辑器切换 2:增加可视化布局插
labview程序代码参考学习使用,希望对你有所帮助。
labview程序代码参考学习使用,希望对你有所帮助。
毕设和企业适用springboot人工智能客服系统类及旅游规划平台源码+论文+视频