Spring boot自定义注解

智数先锋说
• 阅读 11995

本篇文章将介绍如何使用Spring Boot的AOP来简化处理自定义注解,并将通过实现一个简单的方法执行时间统计工具为样例来讲解这些内容。

AOP概念

面向侧面的程序设计(aspect-oriented programming,AOP,又译作面向方面的程序设计、观点导向编程、剖面导向程序设计)是计算机科学中的一个术语,指一种程序设计范型。该范型以一种称为侧面(aspect,又译作方面)的语言构造为基础,侧面是一种新的模块化机制,用来描述分散在对象、类或函数中的横切关注点(crosscutting concern)。

侧面的概念源于对面向对象的程序设计的改进,但并不只限于此,它还可以用来改进传统的函数。与侧面相关的编程概念还包括元对象协议、主题(subject)、混入(mixin)和委托。

注释:以上定义源自中文维基百科(如果访问不了,可以通过修改系统的hosts文件访问,198.35.26.96 zh.wikipedia.org #中文维基百科,只能帮到这了,如果还是上不了,那就麻烦上网搜索下怎么修改系统的hosts文件,不同系统下hosts文件位置不一样,如果是Linux或者Mac系统,我就直接告诉你吧,一般文件路径是/etc/hosts),AOP这个词的翻译有点和国内主流叫法不一致,国内主流都把AOP译做「面向切面编程」,大家不要拘泥于叫法,知道指的是同一个东西即可。

估计,你看了这个定义也是懵的,如果想深入了解可以去知乎看看大佬们是如何掰扯的什么是面向切面编程AOP?。我这边还是就直接上例子了吧。

Spring Boot的AOP环境准备

pom.xml中引入相应的依赖模块

<!-- Spring Boot依赖包 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
</parent>
<dependencies>
    <!-- AOP依赖模块 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <!-- Web依赖模块 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

先实现一个简单的Web请求处理

一个简单的处理Web请求的Controller。

package com.craneyuan.controller;

import com.craneyuan.service.IHelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
    @Autowired
    private IHelloWorldService helloWorldService;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(String name) {
        return helloWorldService.getHelloMessage(name);
    }
}

一个简单的HelloWorld服务实现类,接口的定义我就不展示代码了。

package com.craneyuan.service.impl;

import com.craneyuan.annotation.AnalysisActuator;
import com.craneyuan.service.IHelloWorldService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class HelloWorldServiceImpl implements IHelloWorldService {

    public String getHelloMessage(String name) {
        return "Hello " + Optional.ofNullable(name).orElse("World!");
    }

}

这样一个简单的Web服务就弄好了,你可以启动项目用curl命令调用试下,例如:curl -XGET -i "http://127.0.0.1:8080/hello?name=Java",如果一切顺利的话,你将会得到类似下面这样的响应:

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Date: Thu, 11 Jan 2018 09:45:38 GMT

Hello Java123456

使用自定义注解来统计方法的执行时间

先定义一个用来统计方法执行时间的注解。

package com.craneyuan.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnalysisActuator {
    String note() default "";
}123456789101112

然后定义一个切面,来处理刚刚定义的注解。

package com.craneyuan.aspect;

import com.craneyuan.annotation.AnalysisActuator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnalysisActuatorAspect {
    final static Logger log = LoggerFactory.getLogger(AnalysisActuatorAspect.class);

    ThreadLocal<Long> beginTime = new ThreadLocal<>();

    @Pointcut("@annotation(analysisActuator)")
    public void serviceStatistics(AnalysisActuator analysisActuator) {
    }

    @Before("serviceStatistics(analysisActuator)")
    public void doBefore(JoinPoint joinPoint, AnalysisActuator analysisActuator) {
        // 记录请求到达时间
        beginTime.set(System.currentTimeMillis());
        log.info("cy666 note:{}", analysisActuator.note());
    }

    @After("serviceStatistics(analysisActuator)")
    public void doAfter(AnalysisActuator analysisActuator) {
        log.info("cy666 statistic time:{}, note:{}", System.currentTimeMillis() - beginTime.get(), analysisActuator.note());
    }

}

最后,只要在需要统计执行时间的方法上加上@AnalysisActuator注解就行了。

package com.craneyuan.service.impl;

import com.craneyuan.annotation.AnalysisActuator;
import com.craneyuan.service.IHelloWorldService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class HelloWorldServiceImpl implements IHelloWorldService {

    @AnalysisActuator(note = "获取聊天信息方法")
    public String getHelloMessage(String name) {
        return "Hello " + Optional.ofNullable(name).orElse("World!");
    }

}

启动项目,用curl命令随便调用一下,如果顺利的话就可以观察到切面打印的日志了。

...
cy666 statistic time:4, note:获取聊天信息方法
点赞
收藏
评论区
推荐文章
kenx kenx
4年前
SpringBoot Aop 详解和多种使用场景
前言aop面向切面编程,是编程中一个很重要的思想本篇文章主要介绍的是SpringBoot切面Aop的使用和案例什么是aopAOP(AspectOrientedProgramming):面向切面编程,面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻
Wesley13 Wesley13
3年前
java字节码操作
你知道如何操作JAVA字节码文件吗,这里将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,首先我们来看一下AOP的概念,AOP是OOP的延续,是AspectOrientedProgramming的缩写,意思是面向方面编程。如何操作JAVA字节码文件  本文将介绍与操作Java字节码有关的基本知识和操作Ja
Stella981 Stella981
3年前
Spring 学习笔记(四):Spring AOP
@\TOC\1概述本文主要讲述了AOP的基本概念以及在Spring中AOP的几种实现方式。2AOPAOP,即AspectOrientedProgramming,面向切面编程,与OOP相辅相成。类似的,在OOP中,以类为程序的基本单元,在AOP中的基本单元是Aspect
Easter79 Easter79
3年前
Spring的AOP逐层深入——采用注解完成AOP(七)
上篇博文AOP基本原理6我们介绍了AOP的基本原理,以及5种通知的类型,AOP的两种配置方式:XML配置和Aspectj注解方式。    这篇我们使用注解方式来实现一个AOP,我们先看一下项目的目录。     !(https://static.oschina.net/uploads/img/201801/13190133_UNQ
Stella981 Stella981
3年前
Spring Aspect Oriented Programming
  本文是一篇SpringAOP的基础知识分析文章,其中不牵扯源码分析,只包含AOP中重要概念的讲解,分析,以及SpringAOP的用法。    Spring从2.0版本引入了更加简单却强大的基于xml和AspectJ注解的面向切面的编程方式。在深入了解如何用Spring进行面向切面的编程前,我们先了解AOP中的几个重要的基本概念,这几个概念
Wesley13 Wesley13
3年前
AOP相关概念
1.AOP(面向切面编程)在软件业,AOP为AspectOrientedProgramming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,在软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型.利用AOP
Easter79 Easter79
3年前
Spring中的AOP(三)——基于Annotation的配置方式(一)
    AspectJ允许使用注解用于定义切面、切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理。Spring只是使用了和AspectJ5一样的注解,但并没有使用AspectJ的编译器或者织入器,底层依然使用SpringAOP来实现,依然是在运行时动态生成AOP代理,因此不需要增加额外的编译,也不需要AspectJ的织入器支持。
Easter79 Easter79
3年前
Spring的AOP逐层深入——AOP的基本原理(六)
什么是AOP    AOP(AspectOrientedProgramming),意思是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP基于IoC基础,是对OOP(ObjectOrientedProgramming,面向对象)的延续。同时,AOP实际是GOF设计模式的延续,设计模式孜孜不倦
Stella981 Stella981
3年前
PostSharp 中 AOP 功能的简单使用
本文将介绍如何使用PostSharp中的AOP功能,实现在不修改原业务方法的情况下,记录方法运行的额外信息。PostSharp中AOP功能的简单使用独立观察员2021年2月21日年前在研究 .NET 中如何实现 AOP(AspectOrientedProgramming,面向切面的编程)时看到了一篇叫做《
Wesley13 Wesley13
3年前
Spring AOP教程
一、概念AOP(AspectOrientedProgramming):面向切面编程。面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。二、用途日志记
Wesley13 Wesley13
3年前
Spring学习总结(4)——Spring AOP教程
一、概念AOP(AspectOrientedProgramming):面向切面编程。面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。二、用途日志记
智数先锋说
智数先锋说
Lv1
愿我喜欢的人都能被好运照顾。
文章
5
粉丝
0
获赞
0