IoC原理 Bean生命周期 首先,IoC容器从XML文件或者Java类中读取Bean对象的定义信息,封装成BeanDefinition,并注册到BeanDifinitionRegistry中。
然后,当IoC容器接收到getBean()方法请求时,触发Bean对象的实例化操作。当然,单例模式下如果Bean对象已经存在就直接返回。
在实例化Bean对象之前,回调BeanFactoryPostProcessor,可以对BeanDefinition中保存的信息进行修改,比如修改某些属性值。
通过反射机制实例化Bean对象;
如果Bean对象实现了BeanNameAware接口,则回调setBeanName()方法,传入该bean的id;
如果Bean对象实现了BeanFactoryAware接口,则回调setBeanFactory()方法,传入该Bean的BeanFactory;
如果Bean对象实现了ApplicationContextAware接口,则回调setApplicationContext()方法,传入该Bean的ApplicationContext;
如果有一个Bean实现了BeanPostProcessor接口,则回调postProcessBeforeInitialization()方法;
如果Bean对象实现了InitializingBean接口,则回调afterPropertiesSet()方法;
如果Bean对象配置了init-method方法,则会执行init-method配置的方法;
如果有一个Bean实现了BeanPostProcessor接口,则回调postProcessAfterInitialization()方法;
以下为容器关闭后执行的方法,通常IoC容器一直运行,不会执行
如果Bean对象实现了DisposableBean接口,则回调destroy()方法;
如果Bean对象配置了destroy-method方法,则会执行destroy-method配置的方法。
总结一下:
首先回调BeanFactoryPostProcessor,此时可以修改BeanDefinition;
实例化Bean对象;
回调Bean对象的ApplicationContextAware,返回ApplicationContext;
回调BeanPostProcessor的postProcessBeforeInitialization()方法;
回调Bean对象的InitializingBean,做后初始化操作;
回调Bean对象的init-method方法,做后初始化操作;
回调BeanPostProcessor的postProcessAfterInitialization()方法,此时可以修改Bean对象;
返回Bean对象。
BeanFactory和ApplicationContext BeanFactory和ApplicationContext都可以认为是IoC容器,都提供了getBean()方法。BeanFactory是IoC最基础的接口,getBean()方法就是在BeanFactory接口中声明的。
package org.springframework.beans.factory;public interface BeanFactory { Object getBean (String name) throws BeansException ; }
ApplicationContext继承自BeanFactory,提供了更多功能。
public interface HierarchicalBeanFactory extends BeanFactory {}
package org.springframework.context;public interface ApplicationContext extends EnvironmentCapable , ListableBeanFactory , HierarchicalBeanFactory , MessageSource , ApplicationEventPublisher , ResourcePatternResolver {}
严格意义上BeanFactory是容器,ApplicationContext是应用上下文,由于几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory,所以一般我也把ApplicationContext成为IoC容器。
默认初始化所有的Singleton,也可以通过配置取消预初始化(lazy-init);
继承MessageSource,因此支持国际化;
资源访问,比如访问URL和文件;
事件机制;
同时加载多个配置文件;
以声明式方式启动并创建Spring容器。
IoC源码分析
TODO
入口是AbstractApplicationContext的refresh()方法,我们从这里开始。
package org.springframework.context.support;public abstract class AbstractApplicationContext { public void refresh () throws BeansException, IllegalStateException { synchronized (this .startupShutdownMonitor) { ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); finishBeanFactoryInitialization(beanFactory); } } }
最重要的两个方法是obtainFreshBeanFactory()和finishBeanFactoryInitialization(),前者读取Bean相关配置信息,后者创建Bean实例。
package org.springframework.context.support;public abstract class AbstractApplicationContext { protected ConfigurableListableBeanFactory obtainFreshBeanFactory () { refreshBeanFactory(); return this .beanFactory; } }
package org.springframework.context.support;public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { @Override protected final void refreshBeanFactory () throws BeansException { DefaultListableBeanFactory beanFactory = createBeanFactory(); loadBeanDefinitions(beanFactory); synchronized (this .beanFactoryMonitor) { this .beanFactory = beanFactory; } } }
package org.springframework.beans.factory.support;public class DefaultListableBeanFactory extends AbstractBeanFactory { private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256 ); }
以XML配置为例,AbstractApplicationContext类的子类AbstractXmlApplicationContext实现了loadBeanDefinitions()方法,完成加载和解析XML文件的操作,并将BeanDefinition信息放入到BeanFactory中。其中,BeanDefinition与XML文件中的一个<bean /> 相对应,BeanFactory接口的默认实现类是DefaultListableBeanFactory,可以看到DefaultListableBeanFactory中使用ConcurrentHashMap来保存Bean信息。
这就完成了第一步工作,解析XML文件读取配置信息到BeanFactory的Map中保存。
接下来看看如何根据上面的信息实例化对象。
package org.springframework.context.support;public abstract class AbstractApplicationContext { protected void finishBeanFactoryInitialization (ConfigurableListableBeanFactory beanFactory) { beanFactory.setTempClassLoader(null ); beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); }
AbstractApplicationContext调用BeanFactory的方法来实例化对象。
package org.springframework.beans.factory.support;public class DefaultListableBeanFactory extends AbstractBeanFactory { @Override public void preInstantiateSingletons () throws BeansException { List<String> beanNames = new ArrayList<String>(this .beanDefinitionNames); for (String beanName : beanNames) { getBean(beanName); } } @Override public Object getBean (String name) throws BeansException { return doGetBean(name, null , null , false ); } }
package org.springframework.beans.factory.support;public abstract class AbstractBeanFactory implements BeanFactory { protected <T> T doGetBean (final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { try { 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); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } return (T) bean; } }
DefaultListableBeanFactory类的getBean()方法会调用AbstractBeanFactory类的doGetBean()方法,里面通过createBean()方法创建实例对象。
package org.springframework.beans.factory.support;public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object createBean (String beanName, RootBeanDefinition mbd, Object[] args) { Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final Object[] args) { BeanWrapper instanceWrapper = null ; instanceWrapper = createBeanInstance(beanName, mbd, args); final Object bean = instanceWrapper.getWrappedInstance(); } protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, Object[] args) { } protected BeanWrapper instantiateBean (final String beanName, final RootBeanDefinition mbd) { } }
AbstractAutowireCapableBeanFactory类的createBean()方法
package org.springframework.beans.factory.support;public class SimpleInstantiationStrategy implements InstantiationStrategy { @Override public Object instantiate (RootBeanDefinition bd, String beanName, BeanFactory owner) { Constructor<?> ctor = clazz.getDeclaredConstructor((Class[]) null ); ctor.setAccessible(true ); return ctor.newInstance(null ); } }
package org.springframework.beans.factory.support;public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory { protected void populateBean (String beanName, RootBeanDefinition mbd, BeanWrapper bw) { applyPropertyValues(beanName, mbd, bw, pvs); } protected void applyPropertyValues (String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { MutablePropertyValues mpvs = null ; List<PropertyValue> original; for (PropertyValue pv : original) { } bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } }
package org.springframework.beans;public class BeanWrapperImpl implements BeanWrapper { private class BeanPropertyHandler extends PropertyHandler { private final PropertyDescriptor pd; @Override public void setValue (final Object object, Object valueToApply) throws Exception { final Method writeMethod = (this .pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor) this .pd).getWriteMethodForActualAccess() : this .pd.getWriteMethod()); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) { if (System.getSecurityManager() != null ) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { writeMethod.setAccessible(true ); return null ; } }); } else { writeMethod.setAccessible(true ); } } final Object value = valueToApply; if (System.getSecurityManager() != null ) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run () throws Exception { writeMethod.invoke(object, value); return null ; } }, acc); } catch (PrivilegedActionException ex) { throw ex.getException(); } } else { writeMethod.invoke(getWrappedInstance(), value); } } } }
bean作用域:理解Bean生命周期