spring aop切面编写demo
参考教程链接
http://www.baeldung.com/spring-aop-annotation
AOP的使用
它是一种向现有代码添加行为而不修改该代码的方法。
Maven dependency
<aspectj.version>1.8.5</aspectj.version>
<!--aspect-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
Creating our Custom Annotation 定义我的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
@Target 表示注解的使位置 ElementType.METHOD \/FIELD
@Retention 注释是否在运行时可用于JVM
Creating our Aspect 创建切面
有了注解,就创建开始创建切面,使用注解@Aspect
@Aspect
@Component
public class ExampleAspect {
}
我们还包括了@Component注解,因为我们的类也需要被一个Spring bean来检测。
基本上,这是我们将实现我们想要注入自定义注释的逻辑的类。
Creating our Pointcut and Advice 创建切入点和advice
这将是一个注释方法,它存在于我们的切面:
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
return joinPoint.proceed();
}
从技术上讲,这并不会改变任何事情的行为,但仍然需要分析。
首先,我们用@Around注释了我们的方法。 这是我们的advice,围绕advice意味着我们在方法执行之前和之后添加额外的代码。
接下来,我们的@Around注释有一个切点参数。 我们的切入点只是说,’应用这个advice任何方法用@LogExecutionTime注释’。
还有很多其他类型的切入点,但是如果范围会再次被忽略。
最后,当我们的注释方法最终被调用时,会发生什么,我们的advice将被首先调用。 那么由我们的advice决定下一步做什么。
在我们的例子中,我们的advice除了调用proceed()之外什么都不做,只是调用原来的注释方法。
Logging our Execution Time记录执行时间
现在我们有了我们的骨架,我们需要做的就是为我们的advice添加一些额外的逻辑。
这将是记录执行时间,除了调用原始方法。 我们再补充一下我们的advice:
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
return proceed;
}
再次,我们没有做任何在这里特别复杂的事情。 我们刚刚记录了当前的时间,执行了该方法,然后打印出控制台所需的时间。
我们还记录了使用joinPoint实例提供的方法签名。 如果我们想要,我们也可以访问其他位的信息,比如方法参数getArgs。
如果想把经过处理过的结果作为参数传入方法:
Object[] args = pjp.getArgs();
result = (String) args[0];
proceedResult = ....
String proceedReturn = (String) pjp.proceed(new Object[]{proceedResult});
现在,我们来尝试用@LogExecutionTime注释一个方法,然后执行它来看看会发生什么。 请注意,这必须是一个Spring Bean才能正常工作:
@LogExecutionTime
public void serve() throws InterruptedException {
Thread.sleep(2000);
}
Conclusion 结论
在本文中,我们利用Spring Boot AOP来创建我们的自定义注释,我们可以将其应用于Spring bean,以便在运行时向其注入额外的行为。