Spring源码分析:List集合注入
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>org.example</groupId> <artifactId>spring-boot-test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <java.version>11</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.4.2</spring-boot.version> <spring-cloud.version>2020.0.1</spring-cloud.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version> <knife4j.version>4.1.0</knife4j.version> <hutool.version>5.6.1</hutool.version> <lombok.version>1.18.22</lombok.version> <maven.plugin.version>2.7.8</maven.plugin.version> </properties> <!-- 依赖声明 --> <dependencyManagement> <dependencies> <!-- SpringCloud 微服务 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- SpringCloud Alibaba 微服务 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- SpringBoot 依赖配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--文档插件--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>${knife4j.version}</version> </dependency> <!-- hutool工具 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool.version}</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--SpringBoot Actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--请求参数校验--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build> </project>
EvaluationProcess 接口
package org.example.process; public interface EvaluationProcess { void process(Object object); boolean supports(Integer type); }
ConsultingEvaluationProcess 类
package org.example.process.impl; import org.example.process.EvaluationProcess; import org.springframework.stereotype.Service; @Service public class ConsultingEvaluationProcess implements EvaluationProcess { @Override public void process(Object object) { System.out.println("ConsultingEvaluationProcess"); } @Override public boolean supports(Integer type) { return type == 1; } }
DiagnoseEvaluationProcess类
package org.example.process.impl; import org.example.process.EvaluationProcess; import org.springframework.stereotype.Service; @Service public class DiagnoseEvaluationProcess implements EvaluationProcess { @Override public void process(Object object) { System.out.println("DiagnoseEvaluationProcess"); } @Override public boolean supports(Integer type) { return type == 2; } }
EvaluationService 业务类
package org.example.process; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class EvaluationService { //集合注入 @Autowired private List<EvaluationProcess> evaluationProcesses; private Optional<EvaluationProcess> getProcess(Integer type) { if (this.evaluationProcesses != null) { return this.evaluationProcesses.stream().filter(a -> a.supports(type)).findFirst(); } return Optional.empty(); } public void save() { getProcess(1).ifPresent(origin -> origin.process(null)); } }
ScanConfig 配置
package org.example.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("org.example.process") public class ScanConfig { }
测试类 Test
package org.example.process; import org.example.config.ScanConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Test { public static void main(String[] args) { //纯注解 ApplicationContext c1 = new AnnotationConfigApplicationContext(ScanConfig.class); EvaluationService bean = c1.getBean(EvaluationService.class); bean.save(); } }
源码分析:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
org.springframework.beans.factory.annotation.InjectionMetadata#inject
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver#getLazyResolutionProxyIfNecessary
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans