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
        
      
    
  

---