java自定义注解以及结合AOP的使用
参考过的博客:
1.https://www.cnblogs.com/wangshen31/p/9379197.html 在SpringBoot中用SpringAOP实现日志记录功能
2.https://www.cnblogs.com/bigben0123/p/7779357.html Spring boot中使用aop详解
需求:
1.项目中有这样的需求,执行方法的入参request继承了CommonRequest,在CommonRequest中有个CommonRequestHead属性,在这个请求头中有很多的一些公共参数,比如cifSeq、cifName、useName等等公共字段,已经存储好了。
2.现在我们在执行方法的request中要获取到CommonRequestHead中的一些公共值,并且在方法执行的时候,将这些参数上送;
3.如果在每个方法里面都去写request.setCifSeq(request.getCommonRequestHead.getCifSeq()); 这样的一段话,每个方法都要去加,工作量大,而且代码冗余,不美观,low。
4.考虑使用注解,结合spring的AOP。
5.现在只需要在执行方法上加上一个注解,指定要设置的属性,程序自动帮我去CommonRequestHead中找到cifSeq的值,并且设置在request中。
代码:
1.相关的model:
SubmitRequest:
package com.cy.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class SubmitRequest extends CommonRequest {
private String userName;
private String passWord;
private String cifSeq;
}
CommonRequest:
package com.cy.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CommonRequest {
private CommonRequestHead commonRequestHead;
public CommonRequest() {
this.commonRequestHead = new CommonRequestHead();
}
}
CommonRequestHead:
package com.cy.model;
import lombok.Getter;
import lombok.Setter;
/**
* 假设CommonRequestHead中已经设置好了一些值了,如下
*/
@Getter
@Setter
public class CommonRequestHead {
private String cifSeq = "999999";
private String userName = "张三";
private String passWord = "123456";
}
2.定义注解:
AddRequestParam:
package com.cy.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 给应用注解的方法中的入参,设置你想要的参数名
* paramName: CommonRequestHead中你想要取的属性名称
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AddRequestParam {
String paramName() default "userName";
}
3.切面类:
ParamNameAspect:
package com.cy.annotation;
import com.cy.model.CommonRequestHead;
import com.cy.model.SubmitRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@Component
@Aspect
public class ParamNameAspect {
@Pointcut(value = "@annotation(com.cy.annotation.AddRequestParam)")
public void pointCut() {
}
@Around("pointCut() && @annotation(addRequestParam)")
public Object aroundMethod(ProceedingJoinPoint pjp, AddRequestParam addRequestParam) throws Throwable {
//获取注解里面的值
String paramName = addRequestParam.paramName();
//获取注解方法的参数
Object args = pjp.getArgs()[0];
if(args instanceof SubmitRequest){
SubmitRequest submitRequest = (SubmitRequest) args;
CommonRequestHead commonRequestHead = submitRequest.getCommonRequestHead();
PropertyDescriptor pd = new PropertyDescriptor(paramName, CommonRequestHead.class);
Method getParamValueMethod = pd.getReadMethod(); //获得getCifSeq方法
String paramValue = (String) getParamValueMethod.invoke(commonRequestHead); //获取到commonRequestHead中对应的getCifSeq()的值
//找到SubmitRequest对应的setCifSeq方法,并且设置值
Field[] fields = SubmitRequest.class.getDeclaredFields();
for(Field field : fields){
if(paramName.equals(field.getName())){
PropertyDescriptor spd = new PropertyDescriptor(paramName, SubmitRequest.class);
Method setParamValueMethod = spd.getWriteMethod(); //获得setCifSeq方法
setParamValueMethod.invoke(submitRequest, paramValue); //给submitRequest设置setCifSeq值
}
}
}
return pjp.proceed();
}
}
4.使用Controller进行测试:
package com.cy.controller;
import com.cy.annotation.AddRequestParam;
import com.cy.model.SubmitRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class IndexController {
@ResponseBody
@RequestMapping("/testAddRequestParam")
@AddRequestParam
public String submit(SubmitRequest request, String str){
return request.toString();
}
@ResponseBody
@RequestMapping("/testAddRequestParam2")
@AddRequestParam(paramName = "passWord")
public String submit2(SubmitRequest request, String str){
return request.toString();
}
}
5.浏览器访问测试:
输入:http://localhost:8080/helloSpring/testAddRequestParam 显示:SubmitRequest(userName=张三, passWord=null, cifSeq=null)
输入: http://localhost:8080/helloSpring/testAddRequestParam2 显示:SubmitRequest(userName=null, passWord=123456, cifSeq=null)
6.相关的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">
<modelVersion>4.0.0</modelVersion>
<groupId>helloSpringBoot</groupId>
<artifactId>helloSpringBoot</artifactId>
<version>1.0-SNAPSHOT</version>
<name>helloSpringBoot</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<lombok.version>1.18.20</lombok.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
---
浙公网安备 33010602011771号