SpringBoot实现自动化装配解析
自动化装配步骤:
1.新建一个组件项目2.在resources下新建META-INF/spring.factories新建META-INF/spring-autoconfigure-metadata.properties (可选)(可由 条件注解替代) 3.写一个JavaConfig配置类,并在类中写入需要注入的BeanX4.maven-intall 生成 jar包5.在新项目中引入该jar包的依赖6.直接注入BeanX即可。(IOC容器自动加载)
源码解析
AutoConfigurationImportSelector源码解析
- AutoConfigurationImportSelector是Spring实现自动装配Bean的核心类,selectImports是其核心方法。方法作用:加载spring-autoconfigure-metadata.properties的条件,加载sprng.factories的配置类。然后加入过滤条件,交给IOC去创建对象。
@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}//1.获取classpath下META-INF所有的spring-autoconfidure-metadata.propeerties所有过滤条件AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);//2.获取classpath下META-INF下所有的spring.factories AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);//返回所有需要加载的类的全路径,交给IOC去创建对象 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
2.通过FactoriesClassLoad工具加载META-INF下所有的spring.factories,通过key(注解全路径作为key),获取所有的value,value值为自动注入Bean的全路径,然后加入过滤条件,返回。
/*** Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}* of the importing {@link Configuration @Configuration} class.* @param autoConfigurationMetadata the auto-configuration metadata* @param annotationMetadata the annotation metadata of the configuration class* @return the auto-configurations that should be imported*/protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}
自动化装配实现
根据条件注入Bean
根据条件注入Bean实现方式:
- 基于spring-autoconfigure-metadata.properties配置文件实现
新建项目 gupao-core ,作为一个组件进行编写。无需注入完整的依赖。
包结构:
pom.xml
只需要可以使用@Configuration注解、@Bean注解即可,所以只注入了context包,无需注入完整的spring包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com</groupId><artifactId>gupao-core</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version>
</dependency></dependencies></project>
java代码
@Configuration
@Configuration
public class GuPaoConfig {@Beanpublic Student student(){return new Student();}
}
@Configuration
public class GuPaoOtherConfig {@Beanpublic People people(){return new People();}
}
在resources下新建/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gupao.core.GuPaoConfig,\
com.gupao.core.GuPaoOtherConfig
在resources下新建/META-INF/spring-autoconfigure-metadata.properties
com.gupao.core.GuPaoConfig.ConditionalOnClass=com.differ.demo5.Test
然后使用maven工具 install生成jar包
新建项目 gupao ,引入组件gupao-core,实现自动装配
在gupao的pom.xml中引入组件的依赖。
<dependency><groupId>com</groupId><artifactId>gupao-core</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
@SpringBootApplication
public class App {public static void main(String[] args) {ConfigurableApplicationContext ca = SpringApplication.run(App.class, args);People bean = ca.getBean(People.class);Student dog = ca.getBean(Student.class);System.out.println(bean.say());System.out.println(dog.say());}
}
Console控制台打印
2019-09-03 19:22:05.449 INFO 5640 --- [ main] com.differ.demo5.App : No active profile set, falling back to default profiles: default
2019-09-03 19:22:09.090 INFO 5640 --- [ main] com.differ.demo5.App : Started App in 11.176 seconds (JVM running for 21.484)
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.gupao.core.Student' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:346)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:337)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1123)at com.differ.demo5.App.main(App.java:17)
报错原因: 由于组件加入了条件。 所以必须在主项目中加入相应的条件才不会报错。
在guapo项目中,新建一个类即可。
com.differ.demo5.Test
- 基于条件注解,实现自动装配
基于注解实现—> 条件注解
@ConditionOnClass
@Condi…
…
新建项目 gupao-core ,作为一个组件进行编写。无需注入完整的依赖。
包结构:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com-gupao</groupId><artifactId>gupao-core2</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency></dependencies>
</project>
java代码
@Configuration
@ConditionalOnClass(name={"com.differ.demo5.TestA"})
public class SpringConfig {@Beanpublic People people(){return new People();}
}
在resources下新建/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gupao.core.GuPaoConfig
然后使用maven工具 install生成jar包
新建项目 gupao ,引入组件gupao-core,实现自动装配
在gupao的pom.xml中引入组件的依赖。
<dependency><groupId>com</groupId><artifactId>gupao-core</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
@SpringBootApplication
public class App {public static void main(String[] args) {ConfigurableApplicationContext ca = SpringApplication.run(App.class, args);People bean = ca.getBean(People.class);System.out.println(bean.say());}
}
Console控制台打印
2019-09-03 20:17:25.146 INFO 4672 --- [ main] com.differ.demo5.App : No active profile set, falling back to default profiles: default
2019-09-03 20:17:25.979 INFO 4672 --- [ main] com.differ.demo5.App : Started App in 1.257 seconds (JVM running for 1.705)
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.differ.sb.People' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:346)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:337)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1123)at com.differ.demo5.App.main(App.java:16)
报错原因: 由于组件加入了条件。 所以必须在主项目中加入相应的条件才不会报错。
在guapo项目中,新建一个类即可。
com.differ.demo5.Test
SpringBoot实现自动化装配解析相关推荐
- springboot 自动化装配机制(一)
springboot starter介绍 springboot的出现解决了以往spring繁琐配置的问题,以项目中配置redis为例,以往配置了redis-config之后还需要在spring配置文件 ...
- SpringBoot的自动装配
SpringBoot的自动装配 大致流程 完整流程(结合源码) 启动类 SpringApplication的构造方法 run方法 prepareContext()方法 load()方法 refresh ...
- 【Spring Boot 源码研究 】- 自动化装配机制核心注解剖析
1. 自动化装配介绍 Spring Boot针对mvc做了大量封装,简化开发者的使用,内部是如何管理资源配置,Bean配置,环境变量配置以及启动配置等? 实质是SpringBoot做了大量的注解封装, ...
- Spring学习系列(二) 自动化装配Bean
一.Spring装配-自动化装配 @Component和@ComponentScan 通过spring注解(@Component)来表明该类会作为组件类,并告知Spring要为这类创建bean,不过组 ...
- Jenkins 设置镜像_我常用的SpringBoot+Jenkins自动化部署技巧,贼好用,推荐给大家...
SpringBoot+Jenkins自动化部署技巧,远程部署同样适用,附通用自动化脚本!本文将从半自动化部署讲起,到自动化部署,讲解一套生产环境切实可用的自动化部署方案! 半自动化部署 之前写过的Sp ...
- jenkins 手动执行_我常用的SpringBoot+Jenkins自动化部署技巧,贼好用,推荐给大家...
项目源码地址 项目源码:麻烦转发后关注@JAVA发量告急私信回复[自动化]即可获取! SpringBoot+Jenkins自动化部署技巧,远程部署同样适用,附通用自动化脚本!本文将从半自动化部署讲起, ...
- 【SpringBoot】自动装配原理
[SpringBoot]自动装配原理 文章目录 [SpringBoot]自动装配原理 一.pom.xml 1.spring-boot-dependencies 2.spring-boot-starte ...
- 第2章—装配Bean—自动化装配Bean
自动化装配Bean 2.1.Spring配置可选方案 装配是依赖注入DI的本质,Spring提供了以下三种注入的装配机制: 在XMl中进行显式配置 在java中进行显式配置 隐式的Bean发现机制 ...
- springboot项目配置视图解析器无效的问题
springboot项目配置视图解析器无效的问题 今天springboot尝试配置视图解析器的时候,如图: 一切正常,视图解析器却始终无效.后面发现问题. 在控制器的注解要使用:@Controller ...
最新文章
- POJ3714 Raid 平面最近点对
- linux非阻塞的socket EAGAIN的错误处理【转】
- 宁滨院士生前最后一场学术报告
- c语言实验五函数答案,C语言程序设计实验五 参考答案.doc
- .net问题记录及解决方法
- python在编程序网站_Python的用户登录接口编制以及实现流程图
- 《设计模式》-简单工厂模式
- Linux系统运维人员常用速查表
- JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理
- gdal-3.1.2-release下载页面出错
- Java GUI 铁路售票系统
- PDF是什么格式?如何编辑PDF文件?
- Can‘t locate XXX/XXX.pm in @INC (you may need to install the XXX::XXX module)
- winscp如何连接安卓手机_通过winscp连接路由器
- 痞子衡嵌入式:语音处理工具pzh-speech诞生记(6)- 文语合成实现(pyttsx3, eSpeak1.48.04)...
- 洛谷P4043 费用流
- JavaScript —— 生成随机数
- epub电子书如何用Windows电脑打开?
- 论文阅读:An Empirical Study of Spatial Attention Mechanisms in Deep Networks
- 根因分析-oracle数据库突发性能问题,谁来背这个锅