Springboot自定义注解
常见定义a. 定义注解@Retention 注解功能:指明修饰的注解的生存周期,即会保留到哪个阶段。RetentionPolicy的取值包含以下三种:SOURCE:源码级别保留,编译后即丢弃。CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。@Target 注解功
·
常见定义
a. 定义注解
- @Retention 注解
功能:指明修饰的注解的生存周期,即会保留到哪个阶段。
RetentionPolicy的取值包含以下三种:
SOURCE:源码级别保留,编译后即丢弃。
CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
- @Target 注解
功能:指明了修饰的这个注解的使用范围,即被描述的注解可以用在哪里。
ElementType的取值包含以下几种:
TYPE:类,接口或者枚举
FIELD:域,包含枚举常量
METHOD:方法
PARAMETER:参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
PACKAGE:包
- @Documented 注解
功能:指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。
b. 定义切面
- 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类型.
- 几个注解的解释
@Around 环绕切点,在进入切点前,跟切点后执行
@After 在切点后,return前执行,
@Before 在切点前执行方法,内容为指定的切点
@Aspect 将一个类定义为一个切面类
步骤
自定义注解主要有3步:
- 编写@interface接口
- 编写@interface对应的处理方法进行处理
- 调用处理方法
示例
- 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>qiemian</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>qiemian</name>
<description>qiemian</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 自定义切面 工具类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- FirstAnnotation.java
package com.example.qiemian.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FirstAnnotation {
String value() default "";
}
- FirstAspectj.java
package com.example.qiemian.aspectj;
import com.example.qiemian.annotation.FirstAnnotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class FirstAspectj {
@Pointcut("@annotation(com.example.qiemian.annotation.FirstAnnotation)")
public void annotationPointcut(){
System.out.println("进入切面执行");
}
@Before("annotationPointcut()")
public void beforePointcut(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
FirstAnnotation annotation = method.getAnnotation(FirstAnnotation.class);
String value = annotation.value();
System.out.println("准备:" + value);
}
@After("annotationPointcut()")
public void afterPointcut(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
FirstAnnotation annotation = method.getAnnotation(FirstAnnotation.class);
String value = annotation.value();
System.out.println("结束:" + value);
}
}
- TestController.java
package com.example.qiemian.controller;
import com.example.qiemian.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
TestService testService;
@GetMapping()
public String test(){
testService.doSomething();
return "hello annotation";
}
}
- TestService.java
package com.example.qiemian.service;
public interface TestService {
public void doSomething();
}
- TestServiceImpl
package com.example.qiemian.service.impl;
import com.example.qiemian.annotation.FirstAnnotation;
import com.example.qiemian.service.TestService;
import org.springframework.stereotype.Service;
@Service
public class TestServiceImpl implements TestService {
@FirstAnnotation("吃饭")
@Override
public void doSomething() {
System.out.println("impl:吃饭啦啦啦");
}
}
- QiemianApplication
package com.example.qiemian;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QiemianApplication {
public static void main(String[] args) {
SpringApplication.run(QiemianApplication.class, args);
}
}
运行效果
更多推荐
已为社区贡献3条内容
所有评论(0)