Spring Boot如何手动注册过滤器并实现有序编排?
解决过滤器生效与有序编排问题
你当前的代码只是把Filter类注册为Spring Bean,但并没有将它们纳入Servlet容器的过滤器链中,所以无法生效。要让过滤器生效并实现内置与自定义过滤器的有序编排,可按以下步骤处理:
一、让已注册Filter生效
Spring中,只有将Filter包装为FilterRegistrationBean注册到容器,Servlet才会将其加入过滤器链。修改你的DefaultFilterRegister,替换原注册逻辑:
@Component public class DefaultFilterRegister implements BeanDefinitionRegistryPostProcessor { private List<Filter> toRegister = FilterUtils.getInitFilters(); @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (CollectionUtils.isEmpty(toRegister)) { return; } for (Filter filter : toRegister) { Class<? extends Filter> filterClass = filter.getClass(); String filterBeanName = filterClass.getName(); // 1. 先注册Filter本身作为Spring Bean(支持依赖注入) BeanDefinitionBuilder filterBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition(filterClass); filterBeanBuilder.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE); registry.registerBeanDefinition(filterBeanName, filterBeanBuilder.getRawBeanDefinition()); // 2. 注册FilterRegistrationBean,将Filter纳入Servlet过滤器链 BeanDefinitionBuilder registrationBuilder = BeanDefinitionBuilder.genericBeanDefinition(FilterRegistrationBean.class); registrationBuilder.addConstructorArgReference(filterBeanName); // 设置拦截路径,按需调整,比如/*匹配所有请求 registrationBuilder.addPropertyValue("urlPatterns", Collections.singletonList("/*")); // 给内置过滤器分配默认顺序,值越小越先执行 registrationBuilder.addPropertyValue("order", getDefaultOrder(filter)); registry.registerBeanDefinition(filterBeanName + "Registration", registrationBuilder.getRawBeanDefinition()); } } // 给内置过滤器分配初始顺序 private int getDefaultOrder(Filter filter) { if (filter instanceof AFilter) return 10; if (filter instanceof BFilter) return 20; if (filter instanceof CFilter) return 30; return 100; // 默认顺序 } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} }
二、实现过滤器有序编排(支持addFilterBefore)
要支持自定义过滤器插入指定位置,需要维护全局的过滤器顺序配置,动态调整所有FilterRegistrationBean的order值。
1. 实现过滤器顺序管理器
@Component public class FilterOrderManager { // 用LinkedHashMap维护有序的过滤器类与顺序映射 private final LinkedHashMap<Class<? extends Filter>, Integer> filterOrderMap = new LinkedHashMap<>(); public FilterOrderManager() { // 初始化内置过滤器的默认顺序 filterOrderMap.put(AFilter.class, 10); filterOrderMap.put(BFilter.class, 20); filterOrderMap.put(CFilter.class, 30); } // 将自定义过滤器添加到指定过滤器之前 public void addFilterBefore(Class<? extends Filter> targetFilter, Class<? extends Filter> beforeFilter) { Integer beforeOrder = filterOrderMap.get(beforeFilter); if (beforeOrder == null) { throw new IllegalArgumentException("指定的前置过滤器[" + beforeFilter.getName() + "]不存在"); } // 给后续过滤器的顺序值加10,腾出位置 filterOrderMap.entrySet().forEach(entry -> { if (entry.getValue() >= beforeOrder) { entry.setValue(entry.getValue() + 10); } }); // 设置自定义过滤器的顺序 filterOrderMap.put(targetFilter, beforeOrder); // 重新排序映射,保证顺序正确 reorderMap(); } // 将自定义过滤器添加到指定过滤器之后 public void addFilterAfter(Class<? extends Filter> targetFilter, Class<? extends Filter> afterFilter) { Integer afterOrder = filterOrderMap.get(afterFilter); if (afterOrder == null) { throw new IllegalArgumentException("指定的后置过滤器[" + afterFilter.getName() + "]不存在"); } Integer targetOrder = afterOrder + 10; // 调整后续过滤器顺序,避免冲突 filterOrderMap.entrySet().forEach(entry -> { if (entry.getValue() >= targetOrder) { entry.setValue(entry.getValue() + 10); } }); filterOrderMap.put(targetFilter, targetOrder); reorderMap(); } // 重新排序映射,按order值从小到大排列 private void reorderMap() { List<Map.Entry<Class<? extends Filter>, Integer>> sortedList = new ArrayList<>(filterOrderMap.entrySet()); sortedList.sort(Map.Entry.comparingByValue()); filterOrderMap.clear(); sortedList.forEach(entry -> filterOrderMap.put(entry.getKey(), entry.getValue())); } public LinkedHashMap<Class<? extends Filter>, Integer> getFilterOrderMap() { return filterOrderMap; } }
2. 修改注册逻辑,基于顺序管理器动态注册
更新DefaultFilterRegister,结合FilterOrderManager的配置来注册所有过滤器(包括自定义过滤器):
@Component public class DefaultFilterRegister implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware { private ApplicationContext applicationContext; private List<Filter> toRegister = FilterUtils.getInitFilters(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { FilterOrderManager orderManager = applicationContext.getBean(FilterOrderManager.class); LinkedHashMap<Class<? extends Filter>, Integer> filterOrderMap = orderManager.getFilterOrderMap(); // 注册内置过滤器 registerFilters(registry, toRegister, filterOrderMap); // 注册自定义过滤器(比如用户添加的DFilter) registerCustomFilters(registry, filterOrderMap); } private void registerFilters(BeanDefinitionRegistry registry, List<Filter> filters, LinkedHashMap<Class<? extends Filter>, Integer> orderMap) { for (Filter filter : filters) { registerSingleFilter(registry, filter.getClass(), orderMap); } } private void registerCustomFilters(BeanDefinitionRegistry registry, LinkedHashMap<Class<? extends Filter>, Integer> orderMap) { // 遍历所有在顺序管理器中的过滤器,包括自定义的 for (Class<? extends Filter> filterClass : orderMap.keySet()) { if (!registry.containsBeanDefinition(filterClass.getName())) { // 如果自定义Filter还没注册为Bean,先注册 BeanDefinitionBuilder filterBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition(filterClass); filterBeanBuilder.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE); registry.registerBeanDefinition(filterClass.getName(), filterBeanBuilder.getRawBeanDefinition()); } registerSingleFilter(registry, filterClass, orderMap); } } // 注册单个Filter及其对应的FilterRegistrationBean private void registerSingleFilter(BeanDefinitionRegistry registry, Class<? extends Filter> filterClass, LinkedHashMap<Class<? extends Filter>, Integer> orderMap) { String filterBeanName = filterClass.getName(); Integer order = orderMap.getOrDefault(filterClass, 100); // 注册FilterRegistrationBean(如果不存在则创建,存在则更新order) String registrationBeanName = filterBeanName + "Registration"; if (registry.containsBeanDefinition(registrationBeanName)) { BeanDefinition registrationBean = registry.getBeanDefinition(registrationBeanName); registrationBean.getPropertyValues().add("order", order); } else { BeanDefinitionBuilder registrationBuilder = BeanDefinitionBuilder.genericBeanDefinition(FilterRegistrationBean.class); registrationBuilder.addConstructorArgReference(filterBeanName); registrationBuilder.addPropertyValue("urlPatterns", Collections.singletonList("/*")); registrationBuilder.addPropertyValue("order", order); registry.registerBeanDefinition(registrationBeanName, registrationBuilder.getRawBeanDefinition()); } } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} }
3. 用户使用示例
当用户需要添加DFilter到BFilter之前时,只需调用顺序管理器的方法:
@Autowired private FilterOrderManager filterOrderManager; // 在应用启动时或自定义配置类中调用 public void configureCustomFilters() { filterOrderManager.addFilterBefore(DFilter.class, BFilter.class); }
这样最终过滤器的执行顺序会是:A → D → B → C。
内容的提问来源于stack exchange,提问作者Kusch
相关产品推荐
相关产品推荐

