接着上一篇,LK将IOC的初始化过程沿着各位大佬的足迹梳理了一遍,相信大家都有所收获吧。LK带着大家一起回顾一下,首先我们定位到配置文件的资源,相信这一步大家应该明白我们配置的classpath路径是在哪被解析的。接着资源文件被转换为IO流,IO流又被转换为Document对象,通过解析Document对象我们将配置文件中的资源节点一个个解析,LK重点分析了<bean>节点解析过程和其属性的解析。最后将解析的bean存放在map集合中,注入IOC容器中。
至此IOC初始化结束,那问题来了,所有的bean都被注入到IOC容器中去了,那我怎么去找到我想要的那一个呢?这个过程就是
DI(依赖注入过程),DI主要是向某个对象提供它所需要的其他对象。
分析这个问题我们从getBean()方法入手,看到BeanFactory接口的实现类AbstractApplicationContext。
这个就是获取bean实例的入口方法
@Override
public Object getBean(String name) throws BeansException {
//查看BeanFactory活动状态
assertBeanFactoryActive();
//返回得到的bean实例
return getBeanFactory().getBean(name);
}
进入getBeanFactory()方法它返回ConfigurableListableBeanFactory这个类型,在它的实现类DefaultListableBeanFactory中看到它继承AbstractAutowireCapableBeanFactory类我们在找到它的实现类AbstractBeanFactory。
拔山涉水终于找到我们想要的了,就是doGetBean()这个方法。
@Override
public Object getBean(String name) throws BeansException {
//得到bean的入口
return doGetBean(name, null, null, false);
}
//返回指定be an的实例,该实例可以是共享的,也可以是独立的
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//将别名转换为规范名称
final String beanName = transformedBeanName(name);
Object bean;
//在缓存中找beanName实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//返回缓存中的beanName实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果我们已经创建了这个bean实例,则失败
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 查看工厂中如果存在bean定义
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 不存在,在父类中找
String nameToLookup = originalBeanName(name);
if (args != null) {
// 显示参数委托给父类去得到bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 隐式参数委托给父类去得到bean
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//合并子父bean
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 当前bean依赖bean的初始化.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
registerDependentBean(dependsOnBean, beanName);
getBean(dependsOnBean);
}
}
// 创建bean实例,如果是单例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//是原型.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//创建bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
return (T) bean;
}
这个方法真的很长,抓主线,我们来看创建bean的这个方法,creatbean().
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
//直接看到创建bean的方法
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//实际上创建指定的bean。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// 创建bean的包装类.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从工厂中获取bean实例
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean并初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 初始化bean实例.
Object exposedObject = bean;
try {
//填充包装类中bean的属性值
populateBean(beanName, mbd, instanceWrapper);
}
return exposedObject;
}
LK将方法中的其它判断去了,我们来看看主线内容。
- 先创建了一个包装类BeanWrapper 。
- 初始化bean。
- 给bean赋值。
先来看看初始化过程
//使用适当的实例化策略为指定bean创建一个新实例:工厂方法、构造函数自动连接或简单的实例化。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 解析指定bean定义的bean类,将bean类名解析为类引用(如有必要)并将解析的类存储在bean定义中以供进一步使用。
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());
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 重新创建相同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);
}
}
// 需要确定构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用给定bean的默认构造函数对其进行静态化.
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//获取安全系统接口。
if (System.getSecurityManager() != null) {
//内部类工厂返回给定name的bean
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//将bean转换成包装类
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
//用注册的自定义编辑器初始化给定的beanwrapper和这个工厂。为将创建的beanwrapper调用并填充bean实例。
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
可以看到bean的初始化首先是使用默认的构造函数对其进行静态化,其次使用内部类通过beanname在factory中找到对应bean,最后将其包装成BeanWrapper对象,进行初始化。
看看具体在factory中是怎样通过name得到对应的bean实例的
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
//如果没有重写,不要用cglib重写类。
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
//得到bean的字节码
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
//返回空的构造函数
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//使用给定的构造函数实例化类
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 必须生成cglib子类.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
//通过反射进行构造函数初始化
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
//显示设置它可访问
ReflectionUtils.makeAccessible(ctor);
//返回初始化构造
return ctor.newInstance(args);
}
}
到这初始化完成,来我们一起梳理一下。初始化过程主要是通过初始化构造函数完成的,上面出现的cglib是spring动态代理的常用方式,我们在之后在说。
再来看看属性赋值
//用bean定义中的属性值填充给定beanwrapper中的bean实例。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//得到IOC工厂中的bean定义属性
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 在bean设置属性之前给bean修改的机会
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 如果适用,添加基于名称自动连线的属性值。
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 如果适用,根据类型添加基于autowire的属性值。
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//返回此工厂是否具有InstantiationWareBeanPostProcessor这将在关闭时应用于单例bean。
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//应用给定的属性值,解析此bean工厂中对其他bean的任何运行时引用。必须使用深度复制,因此我们不会永久修改此属性。
applyPropertyValues(beanName, mbd, bw, pvs);
}
//深度拷贝过程
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
//排序
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 创建深度副本,解析值的任何引用。
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 可能将转换后的值存储在合并的bean定义中,
//为了避免对每个创建的bean实例进行重新转换。
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// 设置深度拷贝.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
至此整个属性赋值结束,主要是将bean的已知属性深度拷贝给beanWrapper对象。
现在我们来回过头来梳理一下整个IOC获取指定name的bean的整个过程。
回头看和我们普通bean加载顺序是一致的。
最后再次感谢大佬们。