IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 在spring中实现一个自定义的aop注解 -> 正文阅读

[Java知识库]在spring中实现一个自定义的aop注解

1. Introduction

In this article, we'll implement a custom AOP annotation using the AOP support in Spring.

First, we'll give a high-level overview of AOP, explaining what it is and its advantages. Following this, we'll implement our annotation step by step, gradually building up a more in-depth understanding of AOP concepts as we go.

The outcome will be a better understanding of AOP and the ability to create our custom Spring annotations in the future.

2. What Is an AOP Annotation?

To quickly summarize, AOP stands for aspect orientated programming. Essentially,?it is a way for adding behavior to existing code without modifying that code.

For a detailed introduction to AOP, there are articles on AOP?pointcuts?and?advice. This article assumes we have a basic knowledge already.

The type of AOP that we will be implementing in this article is annotation driven. We may be familiar with this already if we've used the Spring?@Transactional?annotation:

@Transactional
public void orderGoods(Order order) {
   // A series of database calls to be performed in a transaction
}Copy

The key here is non-invasiveness.?By using annotation meta-data, our core business logic isn't polluted with our transaction code. This makes it easier to reason about, refactor, and to test in isolation.

Sometimes, people developing Spring applications can see this as?‘Spring Magic', without thinking in much detail about how it's working. In reality, what's happening isn't particularly complicated. However, once we've completed the steps in this article, we will be able to create our own custom annotation in order to understand and leverage AOP.

3. Maven Dependency

First, let's add our?Maven dependencies.

For this example, we'll be using Spring Boot, as its convention over configuration approach lets us get up and running as quickly as possible:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>Copy

Note that we've included the AOP starter, which pulls in the libraries we need to start implementing aspects.

4. Creating Our Custom Annotation

The annotation we are going to create is one which will be used to log the amount of time it takes a method to execute. Let's create our annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {

}
Copy

Although a relatively simple implementation, it's worth noting what the two meta-annotations are used for.

The?@Target?annotation tells us where our annotation will be applicable. Here we are using?ElementType.Method,?which means it will only work on methods. If we tried to use the annotation anywhere else, then our code would fail to compile. This behavior makes sense, as our annotation will be used for logging method execution time.

And?@Retention?just states whether the annotation will be available to the JVM at runtime or not. By default it is not, so Spring AOP would not be able to see the annotation. This is why it's been reconfigured.

5. Creating Our Aspect

Now we have our annotation, let's create our aspect. This is just the module that will encapsulate our cross-cutting concern, which is our case is method execution time logging. All it is is a class, annotated with?@Aspect:

@Aspect
@Component
public class ExampleAspect {

}Copy

We've also included the?@Component?annotation, as our class also needs to be a Spring bean to be detected. Essentially, this is the class where we will implement the logic that we want our custom annotation to inject.

6. Creating Our Pointcut and Advice

Now, let's create our pointcut and advice. This will be an annotated method that lives in our aspect:

@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
    return joinPoint.proceed();
}Copy

Technically this doesn't change the behavior of anything yet, but there's still quite a lot going on that needs analysis.

First, we have annotated our method with?@Around.?This is our advice, and around advice means we are adding extra code both before and after method execution. There are other types of advice, such as?before?and?after?but they will be left out of scope for this article.

Next, our?@Around?annotation has a point cut argument. Our pointcut just says, ‘Apply this advice any method which is annotated with?@LogExecutionTime.' There are lots of other types of pointcuts, but they will again be left out if scope.

The method?logExecutionTime()?itself is our advice. There is a single argument,?ProceedingJoinPoint.?In our case, this will be an executing method which has been annotated with?@LogExecutionTime.

Finally, when our annotated method ends up being called, what will happen is our advice will be called first. Then it's up to our advice to decide what to do next. In our case, our advice is doing nothing other than calling?proceed(),?which is the just calling the original annotated method.

7. Logging Our Execution Time

Now we have our skeleton in place, all we need to do is add some extra logic to our advice. This will be what logs the execution time in addition to calling the original method. Let's add this extra behavior to our 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;
}Copy

Again, we've not done anything that's particularly complicated here. We've just recorded the current time, executed the method, then printed the amount of time it took to the console. We're also logging the method signature, which is provided to use the?joinpoint?instance. We would also be able to gain access to other bits of information if we wanted to, such as method arguments.

Now, let's try annotating a method with?@LogExecutionTime,?and then executing it to see what happens. Note that this must be a Spring Bean to work correctly:

@LogExecutionTime
public void serve() throws InterruptedException {
    Thread.sleep(2000);
}Copy

After execution, we should see the following logged to the console:

void org.baeldung.Service.serve() executed in 2030msCopy

8. Conclusion

In this article, we've leveraged Spring Boot AOP to create our custom annotation, which we can apply to Spring beans to inject extra behavior to them at runtime.

The source code for our application is available on?over on github; this is a Maven project which should be able to run as is.?

总结一下:我们可以看到,其实实现一个自定义注解很容易,主要是三步:

1、自定义一个注解;

2、定义一个切面类;

3、调用注解

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:40:47  更:2022-10-31 11:45:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 10:04:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码