java自定义注解以及结合AOP的使用
参考过的博客:
1.
2.
需求:
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"?>4.0.0 helloSpringBoot helloSpringBoot 1.0-SNAPSHOT helloSpringBoot UTF-8 1.8 1.8 1.18.20 org.springframework.boot spring-boot-starter-parent 2.4.5 org.projectlombok lombok ${lombok.version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-aop org.projectlombok lombok provided org.springframework.boot spring-boot-configuration-processor true org.springframework spring-test RELEASE compile junit junit maven-clean-plugin 3.1.0 maven-resources-plugin 3.0.2 maven-compiler-plugin 3.8.0 maven-surefire-plugin 2.22.1 maven-jar-plugin 3.0.2 maven-install-plugin 2.5.2 maven-deploy-plugin 2.8.2 maven-site-plugin 3.7.1 maven-project-info-reports-plugin 3.0.0
---