簡體   English   中英

自定義注解過濾器 Spring 開機

[英]Custom annotation filter Spring boot

我看到使用 Spring 啟動非常簡單,創建過濾器。 只需關注這樣的帖子https://www.baeldung.com/spring-boot-add-filter

我找不到的是如何創建將 controller 中的特定端點訂閱到一個過濾器的注釋。

在 Jax-RS 中看起來像

 @GET
    @Path("jax-rs-single")
    @Reactive(ttlRequest = 2000)
    @Produces(MediaType.APPLICATION_JSON)
    public Single getSingle() {
        return Single.just("Hello world single");
    }

@Reactive它將觸發每個請求的 ReactiveFilter 實現。

我還看到了@WebFlow 注釋,但這不是我想要的。 我想創建一個庫,讓消費者決定使用哪個過濾器,只需在 controller 中添加注釋即可。

知道如何用 Spring 啟動/MVC 做類似的事情嗎?

問候

我將在這里嘗試更多地描述自定義注釋和 Spring 中的處理器。

我不知道你想要什么或需要什么,但我會舉一個通用的例子。

您有 2 個選項:

  • 豆處理器
  • 處理程序攔截器

豆處理器

基本上你需要構建 3 樣東西:Annotaton、BeanProcessor 和一個 Callback 來執行你的邏輯(如果有注釋的話)。 這是它的一個示例以及它是如何工作的:

1 - 創建注釋

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface Reactive {
    Integer ttlRequest;
}

2 - 實現一個 BeanPostProcessor

 @Component 
 public class ReactiveAnnotationProcessor implements BeanPostProcessor {

    private ConfigurableListableBeanFactory configurableBeanFactory;

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

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
      throws BeansException {
        this.scanReactiveAnnotation(bean, beanName);
        return bean;
    }

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

    protected void scanReactiveAnnotation(Object bean, String beanName) {
        this.configureMethodInjection(bean);
    }

    private void configureMethodInjection(Object bean) {
        Class<?> managedBeanClass = bean.getClass();
        MethodCallback methodCallback = 
          new ReactiveMethodCallback(configurableBeanFactory, bean);
        ReflectionUtils.doWithMethod(managedBeanClass, methodCallback);
    } 
}

3 - 創建方法回調(這里是執行的邏輯)

public ReactiveMethodCallback implements MethodCallback {

    private ConfigurableListableBeanFactory configurableBeanFactory;
    private Object bean;

    public ReactiveMethodCallback(ConfigurableListableBeanFactory bf, Object bean) {
        configurableBeanFactory = bf;
        this.bean = bean;
    }

    @Override
    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
    if (!method.isAnnotationPresent(Reactive.class)){
      return;
    }
    //YOUR LOGIC HERE
  }

}

這是關於注釋處理的一個很好的來源,它是關於 FieldProcessing 但如果您有疑問,您可以更改接口以實現您需要的內容: https://www.baeldung.com/spring-annotation-bean-pre-processor

[更新] 你也可以創建一個 HandlerInterceptor 代替:

處理程序攔截器

public class ReactiveFilterHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
    Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // Test if the controller-method is annotated with @CustomFilter
            Reactive filter = handlerMethod.getMethod().getAnnotation(Reactive.class);
            if (filter != null) {
                // ... do the filtering, or call the Component for filtering
            }
        }
        return true;
    }
}

並注冊您的處理程序:

@Configuration
public class WebMvcConfig extends WebMvcConfigurer {

  @Autowired 
  ReactiveFilterHandlerInterceptor reactiveFilterHandlerInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(reactiveFilterHandlerInterceptor);
  }
}

如果我正確理解您想要什么,主要問題是如何根據自定義注釋應用過濾器。

因此,首先,是的,您可以使用常規的 Spring 過濾器(在 Spring WebFilter的情況下為 WebFilter 或在 Spring MVC 的情況下為Filter ),但您需要編寫一些自定義邏輯。

要根據注釋進行過濾,您應該:

  1. 使用RequestMappingHandlerMapping#getHandlerInternal()方法檢索對處理請求的方法的引用(在您的情況下為getSingle()
  2. 當您設法檢索HandlerMethod時,您可以檢查該方法是否使用hasMethodAnnotation(Class<A> annotationType)方法應用了您的自定義注釋。
  3. 當您知道這一點時,您可以做出相應的反應:或者chain.doFilter(request, response)不執行任何操作,或者應用您的自定義邏輯,然后觸發過濾器鏈的 rest。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM