使用BeanPostProcessor在Spring中自定义注释 [英] Custom Annotation in Spring with BeanPostProcessor

查看:533
本文介绍了使用BeanPostProcessor在Spring中自定义注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试在Spring中为其余api创建自定义注释.我是创建自定义注释的新手,下面给出了代码段

Spring Boot App-

@SpringBootApplication
@ComponentScan(basePackageClasses = {ServiceController.class, CustomAnnotatorProcessor.class})
public class ServiceApp {
    public static void main(String[] args) {            
        SpringApplication.run(ServiceApp.class, args);
    }
}

RestController-

@RestController
public class ServiceController {

    @RequestMapping(method = RequestMethod.GET, value="/service/v1/version")
    @ApiResponses(value = { 
            @ApiResponse(code = 200, message = "Success", response = String.class),
            @ApiResponse(code = 401, message = "Unauthorized"),
            @ApiResponse(code = 403, message = "Forbidden"),
            @ApiResponse(code = 404, message = "Not Found"),
            @ApiResponse(code = 500, message = "Failure")}) 
    @CustomAnnotation()
    public String getVersion() {
        return "success";
    }
}

自定义注释-

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface CustomAnnotation {

}

注释处理器-

@Component
public class CustomAnnotatorProcessor implements BeanPostProcessor {    

private ConfigurableListableBeanFactory configurableBeanFactory;

@Autowired
public CustomAnnotatorProcessor(ConfigurableListableBeanFactory beanFactory) {
    this.configurableBeanFactory = beanFactory;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    MethodCallback methodCallback = new CustomAnnotationMethodCallback(configurableBeanFactory, bean);
    ReflectionUtils.doWithMethods(bean.getClass(), methodCallback);
    return bean;
}

方法回调-

public class CustomAnnotationMethodCallback implements MethodCallback{
    @Override
    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
        if (method.isAnnotationPresent(CustomAnnotation.class)) {
            System.out.println("doWith is getting called for CustomAnnotationMethodCallback");
            ReflectionUtils.makeAccessible(method);     
            //DO VALIDATION WHETHER A SPECIFIC HEADER IS PRESENT IN THE GIVEN REQUEST
            return;
        }       
    }

}   

我正在尝试在实现BeanPostProcessor的类中处理自定义批注,但是我遇到了问题

问题_1 :回调仅被调用一次,但是我无法对/service/v1/version API中的每个请求都应用验证.我需要针对每个请求进行验证,如果可以的话,我们的设计/方法是否正确,如何解决?

问题_2 :如果我需要将完整的请求对象(带有标头单独)传递给@customAnnotation,该怎么办?

如果您需要更多详细信息,请告诉我

谢谢

解决方案

问题_1 :回调仅被调用一次,但我无法对传入 API.我需要针对每个请求进行验证,如果可以的话,我们的设计/方法是否正确,如何解决?

问题_2 :如果我需要将完整的请求对象(带有标头单独)传递给我的@customAnnotation,我该怎么做?

我认为您应该使用Annotation以外的spring AOP或Interceptor.

We are trying to create a Custom Annotation for our rest api in Spring. I am new to creating custom annotation, I have given the code snippet below

Spring Boot App --

@SpringBootApplication
@ComponentScan(basePackageClasses = {ServiceController.class, CustomAnnotatorProcessor.class})
public class ServiceApp {
    public static void main(String[] args) {            
        SpringApplication.run(ServiceApp.class, args);
    }
}

RestController --

@RestController
public class ServiceController {

    @RequestMapping(method = RequestMethod.GET, value="/service/v1/version")
    @ApiResponses(value = { 
            @ApiResponse(code = 200, message = "Success", response = String.class),
            @ApiResponse(code = 401, message = "Unauthorized"),
            @ApiResponse(code = 403, message = "Forbidden"),
            @ApiResponse(code = 404, message = "Not Found"),
            @ApiResponse(code = 500, message = "Failure")}) 
    @CustomAnnotation()
    public String getVersion() {
        return "success";
    }
}

Custom Annotation --

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface CustomAnnotation {

}

Annotation Processor --

@Component
public class CustomAnnotatorProcessor implements BeanPostProcessor {    

private ConfigurableListableBeanFactory configurableBeanFactory;

@Autowired
public CustomAnnotatorProcessor(ConfigurableListableBeanFactory beanFactory) {
    this.configurableBeanFactory = beanFactory;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    MethodCallback methodCallback = new CustomAnnotationMethodCallback(configurableBeanFactory, bean);
    ReflectionUtils.doWithMethods(bean.getClass(), methodCallback);
    return bean;
}

Method Callback --

public class CustomAnnotationMethodCallback implements MethodCallback{
    @Override
    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
        if (method.isAnnotationPresent(CustomAnnotation.class)) {
            System.out.println("doWith is getting called for CustomAnnotationMethodCallback");
            ReflectionUtils.makeAccessible(method);     
            //DO VALIDATION WHETHER A SPECIFIC HEADER IS PRESENT IN THE GIVEN REQUEST
            return;
        }       
    }

}   

I am trying to process the custom annotation in a class which implements BeanPostProcessor but I have an issue

Issue_1: The callback is getting called once but I am not able apply the validation for every request that is coming to the /service/v1/version API. I need to validate on every request, is our design / approach correct if so how to solve this problem, if not please suggest a different approach

Issue_2: If I need to pass the complete request object (alone with the header) to my @customAnnotation, how should I do that?

Please let me know if you need further details

Thanks

解决方案

Issue_1: The callback is getting called once but I am not able apply the validation for every request that is coming to the /service/v1/version API. I need to validate on every request, is our design / approach correct if so how to solve this problem, if not please suggest a different approach

Issue_2: If I need to pass the complete request object (alone with the header) to my @customAnnotation, how should I do that?

I think you should use spring AOP or Interceptor other than Annotation.

这篇关于使用BeanPostProcessor在Spring中自定义注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆