spring boot之org.springframework.boot.context.TypeExcludeFilter
曾经碰到过这样一种情况,想让某个使用了spring 注解的类不被spring扫描注入到spring bean池中,比如下面的类使用了@Component和@ConfigurationProperties("example1.user")自动绑定属性,不想让这个类被注入。
package com.github.torlight.sbex; import java.io.Serializable; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; @Component
@ConfigurationProperties("example1.user")
public class User implements Serializable{ private static final long serialVersionUID = 6913838730034509179L; private String name; private Integer age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} }
一开始不想使用BeanPostProcessor接口的实现类来实现这样的功能,想可以借助@SpringBootApplication注解,使用exclude来实现该功能。
package com.github.torlight.sbex; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; /**
* Hello world!
*
*/
@SpringBootApplication(exclude={com.github.torlight.sbex.User.class})
public class Example1 { @Bean
public UserAction userAction(){
return new UserAction();
} public static void main( String[] args ) { ApplicationContext context= SpringApplication.run(Example1.class, args); ((UserAction)context.getBean(UserAction.class)).sysOutUserInfo(); }
}
运行程序后,控制台报如下错误:
2018-08-04 13:15:57.079 ERROR 4504 --- [ main] o.s.boot.SpringApplication : Application startup failed org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.github.torlight.sbex.Example1]; nested exception is java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
- com.github.torlight.sbex.User at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:556) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:185) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at com.github.torlight.sbex.Example1.main(Example1.java:25) [classes/:na]
Caused by: java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
- com.github.torlight.sbex.User at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.handleInvalidExcludes(AutoConfigurationImportSelector.java:193) ~[spring-boot-autoconfigure-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.checkExcludedClasses(AutoConfigurationImportSelector.java:178) ~[spring-boot-autoconfigure-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports(AutoConfigurationImportSelector.java:100) ~[spring-boot-autoconfigure-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:547) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
... 14 common frames omitted
错误提示不能使用exclude={com.github.torlight.sbex.User.class},因为该类并不是被spring boot自动装配的类,类似于RedisAutoConfiguration这样的类。仔细研究一番后,发现可以扩展org.springframework.boot.context.TypeExcludeFilter来实现这一功能。spring boot在执行扫描过程中,会使用TypeExcludeFilter进行过滤。
public class TypeExcludeFilter implements TypeFilter, BeanFactoryAware { private BeanFactory beanFactory; @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
} @Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
if (this.beanFactory instanceof ListableBeanFactory
&& getClass().equals(TypeExcludeFilter.class)) {
15 Collection<TypeExcludeFilter> delegates = ((ListableBeanFactory) this.beanFactory)
16 .getBeansOfType(TypeExcludeFilter.class).values();
for (TypeExcludeFilter delegate : delegates) {
if (delegate.match(metadataReader, metadataReaderFactory)) {
return true;
}
}
}
return false;
} @Override
public boolean equals(Object obj) {
throw new IllegalStateException(
"TypeExcludeFilter " + getClass() + " has not implemented equals");
} @Override
public int hashCode() {
throw new IllegalStateException(
"TypeExcludeFilter " + getClass() + " has not implemented hashCode");
} }
可以看出,spring boot会加载spring bean池中所有针对TypeExcludeFilter的扩展,并循环遍历这些扩展类调用其match方法。那么思路出来了,只要继承该类并重写match方法,在该方法内部进行相应的处理即可。示例代码如下:
public class MyTypeExcludeFilter extends TypeExcludeFilter { @Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException { if("com.github.torlight.sbex.User".equals(metadataReader.getClassMetadata().getClassName())){
8 return true;
9 } return false;
} }
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-08-04 13:27:14.556 ERROR 4964 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : ***************************
APPLICATION FAILED TO START
*************************** Description: Field user in com.github.torlight.sbex.UserAction required a bean of type 'com.github.torlight.sbex.User' that could not be found. Action: Consider defining a bean of type 'com.github.torlight.sbex.User' in your configuration.
相关示例代码已经上传到github上面,https://github.com/gittorlight/springboot-example
spring boot之org.springframework.boot.context.TypeExcludeFilter的更多相关文章
- Spring Boot 引入org.springframework.boot.SpringApplication出错
今天新建的一个spring boot maven项目, 写启动类时发现无法引入SpringApplication, 经查原来是冲突了,我早些时候用了比较低版本的spring boot创建了项目 ,导致 ...
- IDEA 创建Spring项目后org.springframework.boot报错
IDEA 创建 Spring boot 项目后 ,在pom.xml文件中 org.springframework.boot出错,刷新也没有作用. 如图: 可以降低 org.springframewor ...
- spring boot 开发 org.springframework.context.ApplicationContextException: Unable to start web server;
Error starting ApplicationContext. To display the conditions report re-run your application with 'de ...
- java.lang.NoClassDefFoundError: org/springframework/boot/context/embedded/FilterRegistrationBean
昨天还好好的, 今天我的spring boot 项目就不能正常运行了! 出现: 018-07-06 10:01:41.776 WARN [mq-service,,,] 7 --- [ main] at ...
- 【spring cloud】spring cloud分布式服务eureka启动时报错:java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
spring cloud分布式服务eureka启动时报错:java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApp ...
- Spring boot java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver
Spring boot 2.0.3 RELEASE 配置报错 java.lang.NoClassDefFoundError: org/springframework/boot/bind/Relaxed ...
- SpringBoot整合nacos启动报错:java.lang.NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
报错信息 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nacosCo ...
- Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/context/embedded/ServletRegistrationBean
异常信息 2017-09-02 18:06:37.223 [main] ERROR o.s.boot.SpringApplication - Application startup failed ja ...
- 构建eureka-server异常ClassNotFoundException: org.springframework.boot.context.embedded.FilterRegistrationBean
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.embedded.FilterRegistr ...
随机推荐
- P2243 电路维修
P2243 电路维修 题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和Jam ...
- Hadoop基础-HDFS的API实现增删改查
Hadoop基础-HDFS的API实现增删改查 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客开发IDE使用的是Idea,如果没有安装Idea软件的可以去下载安装,如何安装 ...
- 安装lsb_release
lsb_release命令用来查看当前系统的发行版信息(prints certain LSB (Linux Standard Base) and Distribution information.). ...
- C\C++中 fopen中文件打开方式的区别:
在C语言中,大家常用到fopen打开文件,准备进行写操作,再用fwrite把数据写入文件,最后用fclose关闭文件. 如以下C代码: #include <stdio.h> char ...
- CSS3 box-sizing:border-box的好处
无论如何改动border,margin与padding的值,都不会导致box总尺寸发生变化.
- HDU 1564 简单博弈 水
n*n棋盘,初始左上角有一个石头,每次放只能在相邻的四个位置之一,不能操作者输. 如果以初始石头编号为1作为后手,那么对于每次先手胜的情况其最后一步的四周的编号必定是奇数,且此时编号为偶数,而对于一个 ...
- TV 开发相关
1.设置全屏,隐藏虚拟按键 1.activity oncreate中 @Override 2 protected void onCreate (Bundle savedInstanceState) { ...
- WPF让人哭笑不得的BUG
前几天遇到了一个让我哭笑不得的bug,我写的Wpf程序在Win7里可以运行,到XP.WindowsServer里运行点击某个控件之后闪退,不报任何错,在后台代码里trycatch也捕捉不到任何异常.很 ...
- 20155213 2016-2017-2 《Java程序设计》第五周学习总结
20155213 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生时显示友好的错误信 ...
- 多进程+协程 处理IO问题
from multiprocessing import Pool import gevent,os import time def recursion(n): if n == 1 or n ==2: ...