一直以来都知道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
相关推荐
- 对于数据库操作,MyBatis的注解如@Select、@Insert、@Update和@Delete可以直接在Mapper接口的方法上使用,将SQL语句与Java代码关联。 - MyBatis的配置文件(mybatis-config.xml)中,设置数据源和...
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
在Spring中,我们可以使用注解来声明切面、切点和通知。下面将详细介绍这些关键组件: 1. **@Aspect**: 这个注解用于标记一个类作为切面,这个类通常会包含切点和通知。 ```java @Aspect public class ...
一个简单的采用自定义注解结合SpringAop实现方法执行的权限管理,这个demo中并没有涉及到与数据库的交互和业务代码,用户权限在登陆时采用简单的手动初始化。该demo用的jdk1.7编译,Spring4.0版本,只想通过这个demo...
标题中的“在自定义Spring AOP中使用EL获取拦截方法的变量值”指的是在Spring的面向切面编程(AOP)中,通过Expression Language(EL,表达式语言)来访问被拦截方法的局部变量值。这通常涉及到Spring的代理机制、...
在这个项目中,我们利用自定义的Aop注解来实现数据源的动态切换。自定义注解可以附加在方法上,当该方法被调用时,AOP会捕获这个调用并执行相应的逻辑,即切换到指定的数据源。 具体实现步骤如下: 1. 定义数据源...
具体实现可能涉及创建Spring配置文件以定义AOP切面,编写Aspect类来实现日志记录,以及在业务服务类上使用注解来标记需要拦截的方法。通过这样的实践,开发者可以更深入地理解这些技术在实际项目中的应用。
总的来说,"spring+springMvc+MyBatis+注解"的组合提供了一套强大的、基于Java的Web应用开发解决方案,利用注解简化配置,使得开发更加高效。而在实际项目中,"dji-misService"可能是一个专注于管理信息系统的后端...
本教程将详细介绍如何利用注解来配置和使用AOP来拦截Controller层的方法,以便记录执行过程中的相关信息,实现日志管理。 一、Spring AOP基础 AOP是Spring框架的核心组件之一,它允许程序员定义“切面”,这些切面...
在"springaop+arg"这个主题中,我们将深入探讨Spring AOP的注解和XML配置方式,以及如何处理AOP中的参数。 首先,让我们从Spring AOP的基础开始。AOP的核心概念是“切面”(Aspect),它封装了横切关注点,如日志、...
本文我们通过Spring AOP和Java的自定义注解来实现日志的插入功能,该方案对原有业务入侵较低,实现较灵活。下面我们将详细介绍该功能的实现原理和相关知识点。 1. 概述 在一般系统中,当我们做了一些重要的操作时...
本篇将深入讲解如何通过注解来配置Spring AOP,以实现更加简洁、高效的代码编写。 首先,我们来看注解在Spring AOP中的应用。在传统的AOP配置中,我们需要定义切入点表达式和通知(advice)在XML配置文件中。然而,...
总结起来,Spring AOP注解版通过简单易懂的注解,使得面向切面编程变得更加直观和方便。它降低了横切关注点与业务逻辑之间的耦合度,提高了代码的可维护性和复用性。通过合理利用这些注解,开发者可以轻松地实现日志...
工程介绍:SpringBoot项目脚手架,利用spring aop+java反射实现自定义注解校验参数 源码里有使用都例子在DemoContorller example1:校验userName参数必填 @CheckParams(notNull = true) private String userName;...
在Spring中,可以使用`@Pointcut`注解来定义切入点,并使用正则表达式或者Spring的表达式语言(SpEL)来指定匹配规则。 4. **关联切面和通知**:使用`@Before`, `@After`, 等注解直接在通知方法上,或者在`@Aspect`...
在Spring AOP中,我们可以通过注解配置来实现切面编程,从而简化代码并提高可维护性。 首先,我们需要了解Spring AOP中的核心概念: 1. **切面(Aspect)**:切面是关注点的模块化,它包含了横切关注点(如日志)和...
在这个主题中,我们将深入探讨Spring AOP如何处理事务管理和注解的使用。 1. **什么是Spring AOP** Spring AOP是基于代理的,它提供了声明式编程,使得程序员可以在不改动业务代码的情况下,添加横切关注点,如...
在IT行业中,Spring框架是Java企业级应用开发的首选,而AOP(面向切面编程)则是Spring框架中一个强大的特性,它允许我们通过定义切面来实现代码的解耦和模块化。AspectJ是一个完全独立的AOP框架,它可以与Spring...
通过理解并实践这个 Spring AOP 注解的例子,你可以更深入地了解如何在实际项目中使用 AOP 来提升代码的可维护性和复用性。无论是日志记录、性能监控还是事务管理,AOP 都能帮助我们编写更加整洁、模块化的代码。