spring boot之org.springframework.boot.context…
2018-08-05 07:46:01来源:博客园 阅读 ()
曾经碰到过这样一种情况,想让某个使用了spring 注解的类不被spring扫描注入到spring bean池中,比如下面的类使用了@Component和@ConfigurationProperties("example1.user")自动绑定属性,不想让这个类被注入。
1 package com.github.torlight.sbex; 2 3 import java.io.Serializable; 4 5 import org.springframework.boot.context.properties.ConfigurationProperties; 6 import org.springframework.stereotype.Component; 7 8 @Component 9 @ConfigurationProperties("example1.user") 10 public class User implements Serializable{ 11 12 private static final long serialVersionUID = 6913838730034509179L; 13 14 private String name; 15 16 private Integer age; 17 18 public String getName() { 19 return name; 20 } 21 22 public void setName(String name) { 23 this.name = name; 24 } 25 26 public Integer getAge() { 27 return age; 28 } 29 30 public void setAge(Integer age) { 31 this.age = age; 32 } 33 34 35 }
一开始不想使用BeanPostProcessor接口的实现类来实现这样的功能,想可以借助@SpringBootApplication注解,使用exclude来实现该功能。
1 package com.github.torlight.sbex; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.annotation.Bean; 7 8 9 /** 10 * Hello world! 11 * 12 */ 13 @SpringBootApplication(exclude={com.github.torlight.sbex.User.class}) 14 public class Example1 { 15 16 17 @Bean 18 public UserAction userAction(){ 19 return new UserAction(); 20 } 21 22 23 public static void main( String[] args ) { 24 25 ApplicationContext context= SpringApplication.run(Example1.class, args); 26 27 ((UserAction)context.getBean(UserAction.class)).sysOutUserInfo(); 28 29 } 30 }
运行程序后,控制台报如下错误:
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进行过滤。
1 public class TypeExcludeFilter implements TypeFilter, BeanFactoryAware { 2 3 private BeanFactory beanFactory; 4 5 @Override 6 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 7 this.beanFactory = beanFactory; 8 } 9 10 @Override 11 public boolean match(MetadataReader metadataReader, 12 MetadataReaderFactory metadataReaderFactory) throws IOException { 13 if (this.beanFactory instanceof ListableBeanFactory 14 && getClass().equals(TypeExcludeFilter.class)) { 15 Collection<TypeExcludeFilter> delegates = ((ListableBeanFactory) this.beanFactory) 16 .getBeansOfType(TypeExcludeFilter.class).values(); 17 for (TypeExcludeFilter delegate : delegates) { 18 if (delegate.match(metadataReader, metadataReaderFactory)) { 19 return true; 20 } 21 } 22 } 23 return false; 24 } 25 26 @Override 27 public boolean equals(Object obj) { 28 throw new IllegalStateException( 29 "TypeExcludeFilter " + getClass() + " has not implemented equals"); 30 } 31 32 @Override 33 public int hashCode() { 34 throw new IllegalStateException( 35 "TypeExcludeFilter " + getClass() + " has not implemented hashCode"); 36 } 37 38 }
可以看出,spring boot会加载spring bean池中所有针对TypeExcludeFilter的扩展,并循环遍历这些扩展类调用其match方法。那么思路出来了,只要继承该类并重写match方法,在该方法内部进行相应的处理即可。示例代码如下:
1 public class MyTypeExcludeFilter extends TypeExcludeFilter { 2 3 @Override 4 public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) 5 throws IOException { 6 7 if("com.github.torlight.sbex.User".equals(metadataReader.getClassMetadata().getClassName())){ 8 return true; 9 } 10 11 return false; 12 } 13 14 }
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
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash