springboot 自定义注解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yb546822612/article/details/88116654

spring注解 一般在记录日志、定时器中使用非常方便,在springmvc框架广泛应用,可以注解的随处可见,近几年流行的springboot框架,更把注解用到了极致,这框架的基本消灭了大部分传统框架上xml配制后改为注解代替,既然注解这么使用这么多,那么如何自定义注解呢

以下例子以springboot中使用自定义注解来简单讲解(源码地址:https://gitee.com/xing_xin/my-annotation.git)

1、建立 my-annotation 工程
工程结构
在这里插入图片描述
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--<parent>-->
        <!--<artifactId>test-demo</artifactId>-->
        <!--<groupId>test-demo</groupId>-->
        <!--<version>1.0-SNAPSHOT</version>-->
    <!--</parent>-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>my-annotation</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

    <!-- 打包spring boot应用 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2、定义注解

 几引用注解的解释
@Documented 注解
    功能:指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。

@Retention 注解
功能:指明修饰的注解的生存周期,即会保留到哪个阶段。
RetentionPolicy的取值包含以下三种:
SOURCE:源码级别保留,编译后即丢弃。
CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。

@Target 注解
功能:指明了修饰的这个注解的使用范围,即被描述的注解可以用在哪里。
ElementType的取值包含以下几种:

TYPE:类,接口或者枚举
FIELD:域,包含枚举常量
METHOD:方法
PARAMETER:参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
PACKAGE:包

package com.test.my.annotation;

import java.lang.annotation.*;

/**
 * Created by Administrator on 2019/2/25/025.
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value() default  "first one";
}

3、定义切面类

Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的.
Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合.
args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation
其中execution 是用的最多的,其格式为:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
returning type pattern,name pattern, and parameters pattern是必须的.
ret-type-pattern:可以为表示任何返回值,全路径的类名等.
name-pattern:指定方法名,代表所以,set,代表以set开头的所有方法.
parameters pattern:指定方法参数(声明的类型),(…)代表所有参数,(
)代表一个参数,(*,String)代表第一个参数为任何值,第二个为String类型.

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * @ClassName TestAspect
 * @Description TODO
 * @Date 2019/2/25/02515:12
 * @Version 1.0
 **/
@Aspect
@Component
public class TestAspect {
   // @Pointcut("execution(public * com.test.my.annotation.TestController.*(..)) && @annotation(com.test.my.annotation.MyAnnotation)" )
    @Pointcut("@annotation(com.test.my.annotation.MyAnnotation)" )
    public void addAdvice(){}
    @Around("addAdvice()")
    public Object Interceptor(ProceedingJoinPoint joinPoint){
        System.out.println("====Interceptor====");
        System.out.println("通知之开始");
        Object retmsg=null;
        try {
            retmsg = joinPoint.proceed();
            System.err.println("++++++++"+retmsg);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("通知之结束 +retmsg+" + retmsg);

        Object result = null;
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            String deviceId = (String) args[0];
            if (!"03".equals(deviceId)) {
                return "no anthorization";
            }
        }
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }
    @Before("addAdvice()")
    public void before(JoinPoint joinPoint){
        MethodSignature sign =  (MethodSignature)joinPoint.getSignature();
        Method method = sign.getMethod();
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        System.out.println("打印:" + annotation.value() + " 开始前");
        //System.out.println("===开始前===");
    }

    @After("addAdvice()")
    public void after() {
        System.out.println("after方法执行后");
    }
}

4、controller 代码

package com.test.my.annotation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName TestController
 * @Description TODO
 * @Date 2019/2/25/02515:07
 * @Version 1.0
 **/
@RestController
public class TestController {
    @MyAnnotation()
    @RequestMapping("/add1")
    public String addData1(String deviceId) {
        System.out.println("=====addData1=====");
        return "success";
    }
    @MyAnnotation()
    @RequestMapping("/add2")
    public String addData2(String deviceId) {
        System.out.println("=====addData2=====");
        return "success";
    }
    @MyAnnotation()
    @RequestMapping("/add3")
    public String addData3(String deviceId) {
        System.out.println("=====addData3=====");
        return "success";
    }

    @MyAnnotation()
    @RequestMapping("/update1")
    public String updateData1(String deviceId) {
        System.out.println("=====updateData1=====");
        return "success";
    }
}

5、application 代码

package com.test.my.annotation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @ClassName TestApplication
 * @Description TODO
 * @Date 2019/2/25/02515:07
 * @Version 1.0
 **/
@SpringBootApplication
@EnableAspectJAutoProxy
public class TestApplication {
    public static void main( String[] args )
    {
        SpringApplication.run(TestApplication.class, args);
    }
}

猜你喜欢

转载自blog.csdn.net/yb546822612/article/details/88116654