SpringBoot实现自动化装配解析

自动化装配步骤:

                 1.新建一个组件项目
                 2.在resources下
                               新建META-INF/spring.factories
                               新建META-INF/spring-autoconfigure-metadata.properties (可选)(可由                                                                    条件注解替代)         
                 3.写一个JavaConfig配置类,并在类中写入需要注入的BeanX
                 4.maven-intall 生成 jar包
                 5.在新项目中引入该jar包的依赖
                 6.直接注入BeanX即可。(IOC容器自动加载)

源码解析

AutoConfigurationImportSelector源码解析
  1. AutoConfigurationImportSelector是Spring实现自动装配Bean的核心类,selectImports是其核心方法。方法作用:加载spring-autoconfigure-metadata.properties的条件,加载sprng.factories的配置类。然后加入过滤条件,交给IOC去创建对象。
@Override
	public 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实现方式:

  1. 基于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 {
	@Bean
	public Student   student(){
		return new Student();
	}
}
@Configuration
public class GuPaoOtherConfig {

	@Bean
	public 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' available
	at 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

  1. 基于条件注解,实现自动装配
     
    基于注解实现—> 条件注解
    @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 {
	
	@Bean
	public 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' available
	at 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值