第一次阅读源码,主要查看的无参构造Bean对象的创建流程,采用debug的方式,会省略没有查看的源码,关注核心问题,其他的部分之后在继续阅读
实体类:
package com.righteye;
public class User {
private String name;
private Integer age;
public User() {
System.out.println("我是无参构造");
}
public User(String name, Integer age) {
System.out.println("我是有参构造");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试:
@Test
public void Test07() {
String config = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
User user = (User) ac.getBean("user");
System.out.println(user);
}
执行后创建出对象
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
核心方法:refresh()
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); // 执行后创建对象
}
}
refresh() 方法很多,用来初始化spring等流程,,首先断点调试寻找创建Bean的那条语句
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // 最终定位这句话
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans. 加载所有单例对象
*/
看注释可发现这个方法用来创建非懒加载的单例对象
调用方法:beanFactory.preInstantiateSingletons() 完成bean对象的创建
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 省略,不关注没有创建Bean的代码
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons(); // 该方法处完成Bean对象的创建
}
疑惑处:点进方法中会有这样一段代码:
获取的beanNames中包含所有xml中配置的信息,通过遍历这些bean信息然后最终调用getBean()方法获取对象
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 方便查看代码, 中间的代码没满足这回查看Bean创建的流程
}
else {
getBean(beanName); // 最终获取对象
}
}
}
进入getBean() 方法,然后发现他是BeanFacotry的重写方法 -》 疑惑:什么是BeanFactory
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false); // 很明显,调用了这个方法
}
继续追踪: AbstractBeanFactory.java 类中的doGetBean()方法,这里我想要创建的bean对象是单例的,所以走了第一个分支,调用getSingleton()
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 中间代码与我这次看的无关
// Create bean instance.
if (mbd.isSingleton()) { // r如果对象是单例的
sharedInstance = getSingleton(beanName, () -> { // 这个地方创建出对象的实例
try {
return createBean(beanName, mbd, args); // 关注这里,一会还能看到
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 后面的代码处理不同的情况:prototype, 其他作用域
}
}
getSingleton()方法,通过给定的名字返回一个单例对象,如果这个对象没有注册执行注册操作
阅读源码,发现在222行 singletonObject = singletonFactory.getObject(); 处实现了对象的创建并且对象的属性填充完毕。
this.singletonObjects: 单例缓存,首先通过beanName去这个缓存中获取对象
singletonObject = singletonFactory.getObject(); 缓存中为空,调用这个方法创建
if (newSingleton) {
// Add the given singleton object to the singleton cache of this factory.
addSingleton(beanName, singletonObject);
}
完整代码:(源码很多不熟的,不敢瞎删,这次主要看三个关注点)
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName); // 关注点
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject(); // 关注这个地方
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject); // 关注这里
}
}
return singletonObject;
}
}
当点击getObject()后,会跳转到之前getSingleton()方法中的匿名内部中,调用 createBean(beanName, mbd, args)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args); // 看这里
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
createBean(beanName, mbd, args)方法,实现了 AbstractBeanFactory 中的方法;看注释中有这样段话:是这个类的核心方法,创建bean的实例,为这个实例填充属性以及调用post-processors等;
这里的post-processors是一种前置处理器,可以用来做一些增强操作
Central method of this class: creates a bean instance, populates the bean instance, applies post-processors, etc.
调用 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 创建实例对象
上面的createBean()是一层跳板:真正创建对象的方法是 doCreateBean
方法签名:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
// 实例对象,没有属性赋值操作
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 实例对象的属性赋值
populateBean(beanName, mbd, instanceWrapper);
简述无参构造函数下bean的创建流程:
1. spring的加载过程会经过一个 refresh()方法,这个方法中会进行许多的操作,其中调用 finishBeanFactoryInitialization 完成非懒加载单例对象的实例化。
2. 执行中,会存在一个BeanNames的集合,里面包含了需要创建的对象信息,然后执行相应的getBean()方法。
3. 最终会调用 AbstractBeanFactory 的核心方法:doGetBean(), 完成实例化(createBeanInstance)和属性的填充(populateBean)
4.最后,在对象实例化后会放入成员变量中的 this.singletonObjects 是工厂中的一个单例缓存
疑惑点:
1. beanDefinitionNames 具体是什么,他如何创建出BeanNames集合
2.beanFactory 的创建时机
3. 有参构造的创建机制
4.如果使用注解或其他配置方法,流程是否相同