Spring源码学习-1.IOC-DefaultListableBeanFactory
2015-07-31 14:06
761 查看
1,spring简介
| spring事务 spring应用|
|
spring AOP | spring JDBC/ORM SpringMVC Spring远程支持
|
| SpringIOC模块(BeanFactory 应用上下文 各种支持实现)
2,Spring Frameword 核心简介:IOC容器实现(依赖反转原理)
1.注入方式:接口注入,setter注入,构造器注入
2.各个组件功能介绍
BeanFactory:IoC容器功能规范BeanDefinition:管理各种对象与他们之间的依赖关系,提供了相应的beanClass、scope、lazyInit属性
3.SpringIoc设计结构
1.BeanFactory <- HierarchicalBeanFactory <-ConfigurableBeanFactoryHierarchicalBeanFactory:继承 BeanFactory ,增加getParentBeanFactory()方法,让Beanfactory具备双亲IOC功能
ConfigurableBeanFactory:Bean后置管理器
2. WebApplicationContext(+ThemeSource) or ConfigurableApplicationContext
<--ApplicationContext(+HierarchicalBeanFactory)(+MessageSource, ApplicationEventPublisher, ResourcePatternResolver)
<--ListableBeanFactory<-BeanFactory
ListableBeanFactory:细化接口功能,如定义getBeanDefinitionNames()功能
通过继承下面三个接口,添加了高级容器的特性支持
MessageSource:这些信息源的扩展功能使得支持国际化
ApplicationEventPublisher:支持应用事件,在上下文中引入事件机制
ResourcePatternResolver:访问资源
3.对于1中的设计路线,主要实现方法是DefaultListableBeanFactory
4.BeanFactory 编程实现
<pre name="code" class="java">public class Demo1 { /** * */ @Test public void helloWorld(){ /* * XMLBeanFactory继承的类 * public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable */ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); RootBeanDefinition siglentonBeanDefinition = new RootBeanDefinition(Model.class); RootBeanDefinition prototypeBeanDefinition = new RootBeanDefinition(Model.class); //调用构造器设置属性值 ConstructorArgumentValues a = new ConstructorArgumentValues(); a.addIndexedArgumentValue(0, "siglentonBeanId"); a.addIndexedArgumentValue(1, "siglentonBeanName"); siglentonBeanDefinition.setConstructorArgumentValues(a); //setXXX()设置属性值 MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.addPropertyValue(new PropertyValue("id", "prototypeBeanId")); propertyValues.addPropertyValue(new PropertyValue("name", "prototypeBeanName")); prototypeBeanDefinition.setPropertyValues(propertyValues); prototypeBeanDefinition.setScope("prototype"); //一个单例Bean 一个原型Bean beanFactory.registerBeanDefinition("siglentonBean", siglentonBeanDefinition); beanFactory.registerBeanDefinition("prototypeBean", prototypeBeanDefinition); Model out1,out2,out3,out4 = null; if(beanFactory.containsBean("siglentonBean")){ System.out.println("siglentonBean isSingleton:"+beanFactory.isSingleton("siglentonBean")); System.out.println("prototypeBean isSingleton:"+beanFactory.isSingleton("prototypeBean")); System.out.println("Test prototype or siglentonBean"); out1 = (Model) beanFactory.getBean("siglentonBean"); out3 = (Model) beanFactory.getBean("siglentonBean"); out2 = (Model) beanFactory.getBean("prototypeBean"); out4 = (Model) beanFactory.getBean("prototypeBean"); System.out.println(out1.getId()+":::::siglentonBean1:"+out1.toString()+" "+out3.getId()+":::::siglentonBean2:"+out3.toString()); System.out.println(out2.getId()+":::::prototypeBean1:"+out2.toString()+" "+out4.getId()+":::::prototypeBean2:"+out4.toString()); } } } class Model { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Model(String id, String name) { super(); this.id = id; this.name = name; } public Model() { super(); } }
运行结果:
siglentonBean isSingleton:true
prototypeBean isSingleton:false
Test prototype or siglentonBean
siglentonBeanId:::::siglentonBean1:Day001Demo.Model@6acd5f8b siglentonBeanId:::::siglentonBean2:Day001Demo.Model@6acd5f8b
prototypeBeanId:::::prototypeBean1:Day001Demo.Model@513bd574 prototypeBeanId:::::prototypeBean2:Day001Demo.Model@2f3adc56
在DefaultListableBeanFactory 调用父类的构造函数是,其中有两个构造函数有一些意义.//RootBeanDefinition的构造函数,设置了Bean的Class属性
public RootBeanDefinition(Class beanClass) {
super();
setBeanClass(beanClass);
}
继续往下走:AbstractBeanDefinition类的构造函数
</pre><pre name="code" class="java">protected AbstractBeanDefinition() { this(null, null); } /** * Create a new AbstractBeanDefinition with the given * constructor argument values and property values. *两种方法给Bean设置默认值 */ protected AbstractBeanDefinition(ConstructorArgumentValues cargs, MutablePropertyValues pvs) { setConstructorArgumentValues(cargs); setPropertyValues(pvs); }
</pre>接下来调用registerBeanDefinition方法,注册BeanDefinition<p></p><p><span style="background-color:rgb(240,240,240)"></span></p><pre name="code" class="java">public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "'beanName' must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { // 校验beanClass是否存在 ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } synchronized (this.beanDefinitionMap) { Object oldBeanDefinition = this.beanDefinitionMap.get(beanName); //如果Map中已经有这个beanName ,并且不允许覆盖原来的beanName的话,抛出异常.如果允许就继续允许,并在日志中留下覆盖的记录 if (oldBeanDefinition != null) { if (!this.allowBeanDefinitionOverriding) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } } else { this.beanDefinitionNames.add(beanName); this.frozenBeanDefinitionNames = null; } //放入Map中 this.beanDefinitionMap.put(beanName, beanDefinition); resetBeanDefinition(beanName); } }接下来就是关键的方法getBean
这个得到Bean实例的实现代码如下:
protected Object doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //name有可能是alias ,也有能是beanName的名字,让他统一转成BeanName final String beanName = transformedBeanName(name); Object bean = null; // 查看singletonObjects这个Map中是否已经有了这个实例或者半成品实例 //private final Map singletonObjects = CollectionFactory.createConcurrentMapIfPossible(16); //这是一个线程安全的Map Object sharedInstance = getSingleton(beanName); if (sharedInstance != 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 + "'"); } } //创建实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // 父BeanFactory已经加载的话,直接返回Bean return parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (int i = 0; i < dependsOn.length; i++) { String dependsOnBean = dependsOn[i]; getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { 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 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } <span style="white-space:pre"> </span>// 这里的实现要比singleton简单,因为不用检查是否已经创建过这个实例 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope 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() {//ObjectFactory 是个接口,这里使用模板方法模式 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); } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return bean; }
</pre><p></p><p>这个getSingleton()方法实现了创建单例的过程 ObjectFactory是个接口,这里用到了模板模式,而createBean()这是个抽象方法,所以使用的策略设计模式</p><pre name="code" class="java">
public Object getSingleton(String beanName, ObjectFactory singletonFactory) { Assert.notNull(beanName, "'beanName' 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 the 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 + "'"); } //创建前将beanName添加到Set中. beforeSingletonCreation(beanName); boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { // singletonObject = singletonFactory.getObject(); } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Iterator it = this.suppressedExceptions.iterator(); it.hasNext();) { ex.addRelatedCause((Exception) it.next()); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //从set集合中移除 afterSingletonCreation(beanName); } addSingleton(beanName, singletonObject); } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
最后实现创建Bean的方法是在AbstractAutowireCapableBeanFactory类的createBean()方法中,代码如下:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { AccessControlContext acc = AccessController.getContext(); //AccessController.doPrivileged()这个方法的作用是不做权限检查 return AccessController.doPrivileged(new PrivilegedAction() { public Object run() { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // Make sure bean class is actually resolved at this point. resolveBeanClass(mbd, beanName); // Prepare method overrides. try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.试着返回一个代理 Object bean = resolveBeforeInstantiation(beanName, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } Object beanInstance = doCreateBean(beanName, mbd, args);//创建实例 if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } }, acc); }
doCreateBean方法如下
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set actualDependentBeans = new LinkedHashSet(dependentBeans.length); for (int i = 0; i < dependentBeans.length; i++) { String dependentBean = dependentBeans[i]; if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; }
doCreateBean方法暂时不分析
相关文章推荐
- Struts2.3.1升级到Struts2.3.24相关问题
- Eclipse+Maven构建web项目三种方式
- springMVC
- Eclipse 快捷键
- Be cautious when using Map and Set in Java
- 英语总结系列(七):Spring
- Java生成数据
- SpringMVC整合Shiro
- 自定义mybatis分页插件
- Java 数组类型(基本类型数组类型、封装类型数组类型、数组的数组类型)
- java 生成4位数的随机数据 70万条
- How to download offline javadoc?
- BASE64,MD5,SHA,HMAC加密與解密算法(java)
- Spring源码:Spring 容器资源加载模板模式应用
- Eclipse报错:java.lang.ClassNotFoundException: ContextLoaderListener
- java多线程
- SpringBoot 中使用 Log4j
- Java读取Unicode文件(UTF-8等)时碰到的BOM首字符问题,及处理方法
- 【Java】java中的compareTo和compare的区别
- JAVA 泛型的类型参数需要注意的地方