Spring Bean 的实例化过程源码解析
程序员考拉
共 10479字,需浏览 21分钟
·
2021-03-26 07:24
引言
1 工程概述
1.1 pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!-- 日志相关依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
1.2 bean
@Data
@Component
public class CqCityBean {
private static final String NAME = "重庆";
public String getCityName(){
return NAME;
}
}
@Data
public class StudentBean {
public final String name = "rosh";
public final Integer age = 18;
public StudentBean(){
System.out.println("invoke StudentBean NoArgsConstructor");
}
}
@Data
@Component
public class XaCityBean {
private static final String NAME = "西安";
public String getCityName(){
return NAME;
}
}
1.3 service
@Service
public class CityService {
@Autowired
public CityService(CqCityBean cq, XaCityBean xa) {
System.out.println(cq.getCityName());
System.out.println(xa.getCityName());
}
}
1.4 applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
default-lazy-init="false">
<context:component-scan base-package="com.rosh.service,com.rosh.bean"/>
<bean id="student" class="com.rosh.bean.StudentBean"/>
</beans>
1.5 RoshTest
public class RoshTest {
@Test
public void mainTest(){
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();
}
}
1.6 运行结果
2 主流程源码Debug
主流程时序图:
3 createBeanInstance 源码解析
描述:该方法主要作用bean的构造方法创建对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果有FactoryMethodName属性
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
/**
* 【1】实例化Bean带有@Autowired注解的构造函数
*
* (1) 找到带有@Autowired注解的有参构造函数
* (2) 使用构造函数创建对象
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 调用无参构造方法创建bean
return instantiateBean(beanName, mbd);
}
3.1 创建无参bean对象
描述:使用反射调用无参构造函数创建对象
3.2 @Autowired构造创建有参对象
3.2.1 AutowiredAnnotationBeanPostProcessor
determineCandidateConstructors 方法分析,获取@Autowired 有参构造函数
3.2.2 ConstructorResolver
ConstructorResolver类autowireConstructor方法创建对象
描述:创建参数
3.3 无@Autowired 构造创建有参对象
3.3.1 Debug
AutowiredAnnotationBeanPostProcessor 检查:
原文链接:https://blog.csdn.net/qq_34125999/article/details/114858004
关注GitHub今日热榜,专注挖掘好用的开发工具,致力于分享优质高效的工具、资源、插件等,助力开发者成长!
点个在看 你最好看
评论