[英]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
),但您需要編寫一些自定義邏輯。
要根據注釋進行過濾,您應該:
RequestMappingHandlerMapping#getHandlerInternal()
方法檢索對處理請求的方法的引用(在您的情況下為getSingle()
)HandlerMethod
時,您可以檢查該方法是否使用hasMethodAnnotation(Class<A> annotationType)
方法應用了您的自定義注釋。chain.doFilter(request, response)
不執行任何操作,或者應用您的自定義邏輯,然后觸發過濾器鏈的 rest。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.