常见定义

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步:

  1. 编写@interface接口
  2. 编写@interface对应的处理方法进行处理
  3. 调用处理方法
示例
  • 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);
    }

}

运行效果

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐