深入探索IOC容器的实质
来源:互联网 发布:python 折线图 编辑:程序博客网 时间:2024/05/15 12:17
IOC容器初始化时,创建所有单例的bean,今天深入探索IOC容器的实质:
其内部的创建代码如下:
调用了本类的另一个构造器方法
根据beanName获取所有单例模式的bean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
而singtonObjects,此属性的定义如下:
我们发现这些单例的对象其实是保存在一个map中
这个所谓的IOC容器就是一个map,所有的单例都保存在这个map中
具体流程:
ioc容器一启动就调用初始化---->AbstractApplicationContext.refresh()---->初始化所有的单实例对象
---->AbstractApplicationContext.finishBeanFactoryInitialization()----->调用getBean初始化bean
---->所有的getbean又调用AbstractBeanFactory.doGetbean();---->调用doGetBean的getSingleton(beanName);
---->第一次ioc初始化烦hi的是null,第二去调用getBean通过这个方法就已经返回了
bean实例,调用的是DefaultSingletonBeanRegistry.getSingleton();
就是从singletonObjects里面拿出对应的bean。
singletonObjects是一个map,声明如下,
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
这就是我们保存所有单实例对象的地方,ioc容器。
IOC容器初始化即创建ClassPathXmlApplicationContext对象,如下:
ApplicationContext ioc = new ClassPathXmlApplicationContex("applicationContext.xml");
其内部的创建代码如下:
ClassPathXmlApplicationContext类中的构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}
调用了本类的另一个构造器方法
ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);//设置本地参数setConfigLocations(configLocations);if (refresh) {//创建IOC容器refresh();}}
创建IOC容器的方法在org.springframework.context.support.AbstractApplicationContext
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//准备beanFactory// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();//初始化beanFactory// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
初始化beanFactory即调用本类的方法,如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();//初始化所有的单实例bean// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}
至此初始化所有的单实例bean,调用org.springframework.beans.factory.support.DefaultListableBeanFactory的preInstantiateSingletons()方法
//创建所有的单实例bean@Overridepublic void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}List<String> beanNames;//获得所有beanNamesynchronized (this.beanDefinitionMap) {// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.beanNames = new ArrayList<String>(this.beanDefinitionNames);}//遍历所有beanName的集合for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {//从IOC容器中获取bean,如果没有这个bean,//就去创建一个bean,并返回,如果有就从容器中拿 getBean(beanName);}}}}
从IOC容器中获取bean,即执行org.springframework.beans.factory.support.AbstractBeanFactory类中的getBean方法
@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}@Overridepublic Object getBean(String name, Object... args) throws BeansException {return doGetBean(name, null, args, false);}
所有的getbean方法皆调用了本类的doGetBean方法
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {...//根据beanName获得所有单例模式的beanObject sharedInstance = getSingleton(beanName);...
根据beanName获取所有单例模式的bean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
如下即是具体的方法代码
@Overridepublic Object getSingleton(String beanName) {return getSingleton(beanName, true);}protected Object getSingleton(String beanName, boolean allowEarlyReference) {//从这个类的singletonObjects属性中获取Object singletonObject = this.singletonObjects.get(beanName);...
而singtonObjects,此属性的定义如下:
/** Cache of singleton objects: bean name --> bean instance */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
我们发现这些单例的对象其实是保存在一个map中
这个所谓的IOC容器就是一个map,所有的单例都保存在这个map中
具体流程:
ioc容器一启动就调用初始化---->AbstractApplicationContext.refresh()---->初始化所有的单实例对象
---->AbstractApplicationContext.finishBeanFactoryInitialization()----->调用getBean初始化bean
---->所有的getbean又调用AbstractBeanFactory.doGetbean();---->调用doGetBean的getSingleton(beanName);
---->第一次ioc初始化烦hi的是null,第二去调用getBean通过这个方法就已经返回了
bean实例,调用的是DefaultSingletonBeanRegistry.getSingleton();
就是从singletonObjects里面拿出对应的bean。
singletonObjects是一个map,声明如下,
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
这就是我们保存所有单实例对象的地方,ioc容器。
2 0
- 深入探索IOC容器的实质
- Blade源码深入探索1--注册路由之ioc容器
- Spring IoC容器的深入理解
- Spring的IOC容器创建过程深入剖析
- 深入剖析Spring(二)——IoC容器的实现
- 深入研究Spring-IoC :容器创建的几种方式
- Spring4深入理解IOC&DI03----Bean配置--SpEL,IOC 容器中 Bean 的生命周期
- 深入理解C#委托的实质
- 深入理解C#委托的实质
- 深入理解C#委托的实质
- IOC容器的理解
- spring的Ioc容器
- Jbpm4的IOC容器
- Spring的IoC容器
- IoC容器的实现
- IOC容器的基本原理
- spring的IOC容器
- IOC容器的实现
- 省略号
- 2016-12-10
- UnityShader:选择Pass渲染通道
- 第十六周 项目一 - 归并排序
- 1061. 判断题(15)
- 深入探索IOC容器的实质
- JAVA WEB 学习笔记 Tomcat配置-附光纤光猫破解。
- 布隆过滤器
- 第十六周 项目一 - 基数排序
- JavaSE学习笔记之NIO.2
- Mac Eclipse Tomcat 权限问题
- Android 微信第三方登录(个人笔记)
- 1063. 计算谱半径(20)
- 基数排序总结