当前位置:首页 > 开发 > 开源软件 > 正文

分析Spring源代码之,DI的实现

发表于: 2012-04-07   作者:aijuans   来源:转载   浏览:
摘要: (转) 分析Spring源代码之,DI的实现 2012/1/3 by tony                 接着上次的讲,以下这个sample [java]  view plain copy print

(转)

分析Spring源代码之,DI的实现

2012/1/3 by tony

                接着上次的讲,以下这个sample

[java]  view plain copy print ?
  1. package com.hyron.tony;  
  2. import org.springframework.beans.factory.BeanFactory;  
  3. import org.springframework.beans.factory.xml.XmlBeanFactory;  
  4. import org.springframework.core.io.ClassPathResource;  
  5.   
  6. public class Test {  
  7.   
  8.     public static void main(String[] args)throws Exception {  
  9.         BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));  
  10.         GreetingService greetingService = (GreetingService)factory.getBean("greetingService");  
  11.         greetingService.sayGreeting();  
  12.     }  
  13.   
  14. }  

Bean的实时启动,就是以下这行代码:

[java]  view plain copy print ?
  1. (GreetingService)factory.getBean("greetingService");  

他的执行树如下:

Factory.getBean

-- XmlBeanFactory

--AbstractAutowireCapableBeanFactory

-- AbstractBeanFactory 在其中找到如下方法

[java]  view plain copy print ?
  1. //---------------------------------------------------------------------  
  2.     // Implementation of BeanFactory interface  
  3.     //---------------------------------------------------------------------  
  4.   
  5.     public Object getBean(String name) throws BeansException {  
  6.         return doGetBean(name, nullnullfalse);  
  7.     }  

 

doGetBean的方法声明:

[java]  view plain copy print ?
  1. /** 
  2.      * Return an instance, which may be shared or independent, of the specified bean. 
  3.      * @param name the name of the bean to retrieve 
  4.      * @param requiredType the required type of the bean to retrieve 
  5.      * @param args arguments to use if creating a prototype using explicit arguments to a 
  6.      * static factory method. It is invalid to use a non-null args value in any other case. 
  7.      * @param typeCheckOnly whether the instance is obtained for a type check, 
  8.      * not for actual use 
  9.      * @return an instance of the bean 
  10.      * @throws BeansException if the bean could not be created 
  11.      */  
  12.     @SuppressWarnings("unchecked")  
  13.     protected <T> T doGetBean(  
  14.             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
  15.             throws BeansException {  
  16. }  

 

我真觉得有时候研究人家代码真不如看人家注释,特别是很好的开源架构,代码是好得很

doGetBean方法中比较有意思的代码如下:

//将beanName前面可能的&符号滤掉

[java]  view plain copy print ?
  1. final String beanName = transformedBeanName(name);  

 

//得到已经登记过的单例Object,而不是再次生成它

[java]  view plain copy print ?
  1. Object sharedInstance = getSingleton(beanName);  

 

它的具体代码如下:

[java]  view plain copy print ?
  1. /** 
  2.      * Return the (raw) singleton object registered under the given name. 
  3.      * <p>Checks already instantiated singletons and also allows for an early 
  4.      * reference to a currently created singleton (resolving a circular reference). 
  5.      * @param beanName the name of the bean to look for 
  6.      * @param allowEarlyReference whether early references should be created or not 
  7.      * @return the registered singleton object, or <code>null</code> if none found 
  8.      */  
  9.     protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
  10.         Object singletonObject = this.singletonObjects.get(beanName);  
  11.         if (singletonObject == null) {  
  12.             synchronized (this.singletonObjects) {  
  13.                 singletonObject = this.earlySingletonObjects.get(beanName);  
  14.                 if (singletonObject == null && allowEarlyReference) {  
  15.                     ObjectFactory singletonFactory = this.singletonFactories.get(beanName);  
  16.                     if (singletonFactory != null) {  
  17.                         singletonObject = singletonFactory.getObject();  
  18.                         this.earlySingletonObjects.put(beanName, singletonObject);  
  19.                         this.singletonFactories.remove(beanName);  
  20.                     }  
  21.                 }  
  22.             }  
  23.         }  
  24.         return (singletonObject != NULL_OBJECT ? singletonObject : null);  
  25.     }  

 

其中有一点比较有意思,就是singletonFactories是在哪里塞入的

以下:

[java]  view plain copy print ?
  1. /** 
  2.      * Add the given singleton factory for building the specified singleton 
  3.      * if necessary. 
  4.      * <p>To be called for eager registration of singletons, e.g. to be able to 
  5.      * resolve circular references. 
  6.      * @param beanName the name of the bean 
  7.      * @param singletonFactory the factory for the singleton object 
  8.      */  
  9.     protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {  
  10.         Assert.notNull(singletonFactory, "Singleton factory must not be null");  
  11.         synchronized (this.singletonObjects) {  
  12.             if (!this.singletonObjects.containsKey(beanName)) {  
  13.                 this.singletonFactories.put(beanName, singletonFactory);  
  14.                 this.earlySingletonObjects.remove(beanName);  
  15.                 this.registeredSingletons.add(beanName);  
  16.             }  
  17.         }  
  18.     }  

 

这个方法被执行与createBean

createBean的执行其实是在doGetBean方法内本身

接下来从一个BeanFactory中获得对象的instance

[java]  view plain copy print ?
  1. /** 
  2.      * Get the object for the given bean instance, either the bean 
  3.      * instance itself or its created object in case of a FactoryBean. 
  4.      * @param beanInstance the shared bean instance 
  5.      * @param name name that may include factory dereference prefix 
  6.      * @param beanName the canonical bean name 
  7.      * @param mbd the merged bean definition 
  8.      * @return the object to expose for the bean 
  9.      */  
  10.     protected Object getObjectForBeanInstance(  
  11.             Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  
  12.   
  13.         // Don't let calling code try to dereference the factory if the bean isn't a factory.  
  14.         if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {  
  15.             throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());  
  16.         }  
  17.   
  18.         // Now we have the bean instance, which may be a normal bean or a FactoryBean.  
  19.         // If it's a FactoryBean, we use it to create a bean instance, unless the  
  20.         // caller actually wants a reference to the factory.  
  21.         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {  
  22.             return beanInstance;  
  23.         }  
  24.   
  25.         Object object = null;  
  26.         if (mbd == null) {  
  27.             object = getCachedObjectForFactoryBean(beanName);  
  28.         }  
  29.         if (object == null) {  
  30.             // Return bean instance from factory.  
  31.             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;  
  32.             // Caches object obtained from FactoryBean if it is a singleton.  
  33.             if (mbd == null && containsBeanDefinition(beanName)) {  
  34.                 mbd = getMergedLocalBeanDefinition(beanName);  
  35.             }  
  36.             boolean synthetic = (mbd != null && mbd.isSynthetic());  
  37.             object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
  38.         }  
  39.         return object;  
  40.     }  

 

否则的话,失败的话,则从BeanFacory中动态生成对象实例

[java]  view plain copy print ?
  1. // Fail if we're already creating this bean instance:  
  2.             // We're assumably within a circular reference.  
  3.             if (isPrototypeCurrentlyInCreation(beanName)) {  
  4.                 throw new BeanCurrentlyInCreationException(beanName);  
  5.             }  
  6.   
  7.             // Check if bean definition exists in this factory.  
  8.             BeanFactory parentBeanFactory = getParentBeanFactory();  
  9.             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
  10.                 // Not found -> check parent.  
  11.                 String nameToLookup = originalBeanName(name);  
  12.                 if (args != null) {  
  13.                     // Delegation to parent with explicit args.  
  14.                     return (T) parentBeanFactory.getBean(nameToLookup, args);  
  15.                 }  
  16.                 else {  
  17.                     // No args -> delegate to standard getBean method.  
  18.                     return parentBeanFactory.getBean(nameToLookup, requiredType);  
  19.                 }  
  20.             }  


 以上这段代码真的很让人费解,什么是BeanFactory,什么是FactoryBean

 

接下来,如果在失败,就直接createBean

[java]  view plain copy print ?
  1. // Create bean instance.  
  2.         if (mbd.isSingleton()) {  
  3.             sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
  4.                 public Object getObject() throws BeansException {  
  5.                     try {  
  6.                         return createBean(beanName, mbd, args);  
  7.                     }  
  8.                     catch (BeansException ex) {  
  9.                         // Explicitly remove instance from singleton cache: It might have been put there  
  10.                         // eagerly by the creation process, to allow for circular reference resolution.  
  11.                         // Also remove any beans that received a temporary reference to the bean.  
  12.                         destroySingleton(beanName);  
  13.                         throw ex;  
  14.                     }  
  15.                 }  
  16.             });  
  17.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
  18.         }  


其中createBean是写在父类中的抽象类 AbstractAutowireCapableBeanFactory中

[java]  view plain copy print ?
  1. /** 
  2.      * Central method of this class: creates a bean instance, 
  3.      * populates the bean instance, applies post-processors, etc. 
  4.      * @see #doCreateBean 
  5.      */  
  6.     @Override  
  7.     protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  
  8.             throws BeanCreationException {  
  9.   
  10.         if (logger.isDebugEnabled()) {  
  11.             logger.debug("Creating instance of bean '" + beanName + "'");  
  12.         }  
  13.         // Make sure bean class is actually resolved at this point.  
  14.         resolveBeanClass(mbd, beanName);  
  15.   
  16.         // Prepare method overrides.  
  17.         try {  
  18.             mbd.prepareMethodOverrides();  
  19.         }  
  20.         catch (BeanDefinitionValidationException ex) {  
  21.             throw new BeanDefinitionStoreException(mbd.getResourceDescription(),  
  22.                     beanName, "Validation of method overrides failed", ex);  
  23.         }  
  24.   
  25.         try {  
  26.             // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
  27.             Object bean = resolveBeforeInstantiation(beanName, mbd);  
  28.             if (bean != null) {  
  29.                 return bean;  
  30.             }  
  31.         }  
  32.         catch (Throwable ex) {  
  33.             throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
  34.                     "BeanPostProcessor before instantiation of bean failed", ex);  
  35.         }  
  36.   
  37.         Object beanInstance = doCreateBean(beanName, mbd, args);  
  38.         if (logger.isDebugEnabled()) {  
  39.             logger.debug("Finished creating instance of bean '" + beanName + "'");  
  40.         }  
  41.         return beanInstance;  
  42.     }  

 

其中真正反射生成对象instance的是

[java]  view plain copy print ?
  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   


这个方法分成两部分:

第一,生成对象instance的Wapper,用到了包装者模式

[java]  view plain copy print ?
  1. if (instanceWrapper == null) {  
  2.             instanceWrapper = createBeanInstance(beanName, mbd, args);  
  3.         }  


第二,实例化对象instance

[java]  view plain copy print ?
  1. // Initialize the bean instance.  
  2.         Object exposedObject = bean;  
  3.         try {  
  4.             populateBean(beanName, mbd, instanceWrapper);  
  5.             if (exposedObject != null) {  
  6.                 exposedObject = initializeBean(beanName, exposedObject, mbd);  
  7.             }  
  8.         }  
  9.         catch (Throwable ex) {  
  10.             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {  
  11.                 throw (BeanCreationException) ex;  
  12.             }  
  13.             else {  
  14.                 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
  15.             }  
  16.         }  


其中createBeanInstance中最简单的生成期是

[java]  view plain copy print ?
  1. // No special handling: simply use no-arg constructor.  
  2.         return instantiateBean(beanName, mbd);  


它的核心代码:

[java]  view plain copy print ?
  1. if (System.getSecurityManager() != null) {  
  2.                 beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {  
  3.                     public Object run() {  
  4.                         return getInstantiationStrategy().instantiate(mbd, beanName, parent);  
  5.                     }  
  6.                 }, getAccessControlContext());  
  7.             }  
  8.             else {  
  9.                 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);  
  10.             }  


这里使用了策略模式,将实际的算法放到策略接口中去

 

一般最简单的实现的策略模式就是:

[java]  view plain copy print ?
  1. /** 
  2.  * Default object instantiation strategy for use in BeanFactories. 
  3.  * Uses CGLIB to generate subclasses dynamically if methods need to be 
  4.  * overridden by the container, to implement Method Injection. 
  5.  * 
  6.  * <p>Using Method Injection features requires CGLIB on the classpath. 
  7.  * However, the core IoC container will still run without CGLIB being available. 
  8.  * 
  9.  * @author Rod Johnson 
  10.  * @author Juergen Hoeller 
  11.  * @since 1.1 
  12.  */  
  13. public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {  

 

[java]  view plain copy print ?
  1. /** 
  2.          * Create a new instance of a dynamically generated subclasses implementing the 
  3.          * required lookups. 
  4.          * @param ctor constructor to use. If this is <code>null</code>, use the 
  5.          * no-arg constructor (no parameterization, or Setter Injection) 
  6.          * @param args arguments to use for the constructor. 
  7.          * Ignored if the ctor parameter is <code>null</code>. 
  8.          * @return new instance of the dynamically generated class 
  9.          */  
  10.         public Object instantiate(Constructor ctor, Object[] args) {  
  11.             Enhancer enhancer = new Enhancer();  
  12.             enhancer.setSuperclass(this.beanDefinition.getBeanClass());  
  13.             enhancer.setCallbackFilter(new CallbackFilterImpl());  
  14.             enhancer.setCallbacks(new Callback[] {  
  15.                     NoOp.INSTANCE,  
  16.                     new LookupOverrideMethodInterceptor(),  
  17.                     new ReplaceOverrideMethodInterceptor()  
  18.             });  
  19.   
  20.             return (ctor == null) ?   
  21.                     enhancer.create() :   
  22.                     enhancer.create(ctor.getParameterTypes(), args);  
  23.         }  


真正最终的对象生成器是

[java]  view plain copy print ?
  1. net.sf.cglib.proxy.Enhancer;  

 

spring没有用原生态的代理反射,而是用这个开源jar包来实现了动态生成

 

最后spring对对象的实例化,和参数的注入,是以下代码:

[java]  view plain copy print ?
  1. /** 
  2.      * Populate the bean instance in the given BeanWrapper with the property values 
  3.      * from the bean definition. 
  4.      * @param beanName the name of the bean 
  5.      * @param mbd the bean definition for the bean 
  6.      * @param bw BeanWrapper with bean instance 
  7.      */  
  8.     protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {  
  9.         PropertyValues pvs = mbd.getPropertyValues();  
  10.   
  11.         if (bw == null) {  
  12.             if (!pvs.isEmpty()) {  
  13.                 throw new BeanCreationException(  
  14.                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");  
  15.             }  
  16.             else {  
  17.                 // Skip property population phase for null instance.  
  18.                 return;  
  19.             }  
  20.         }  
  21.   
  22.         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the  
  23.         // state of the bean before properties are set. This can be used, for example,  
  24.         // to support styles of field injection.  
  25.         boolean continueWithPropertyPopulation = true;  
  26.   
  27.         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
  28.             for (BeanPostProcessor bp : getBeanPostProcessors()) {  
  29.                 if (bp instanceof InstantiationAwareBeanPostProcessor) {  
  30.                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
  31.                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {  
  32.                         continueWithPropertyPopulation = false;  
  33.                         break;  
  34.                     }  
  35.                 }  
  36.             }  
  37.         }  
  38.   
  39.         if (!continueWithPropertyPopulation) {  
  40.             return;  
  41.         }  
  42.   
  43.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
  44.                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
  45.             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
  46.   
  47.             // Add property values based on autowire by name if applicable.  
  48.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
  49.                 autowireByName(beanName, mbd, bw, newPvs);  
  50.             }  
  51.   
  52.             // Add property values based on autowire by type if applicable.  
  53.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
  54.                 autowireByType(beanName, mbd, bw, newPvs);  
  55.             }  
  56.   
  57.             pvs = newPvs;  
  58.         }  
  59.   
  60.         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
  61.         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
  62.   
  63.         if (hasInstAwareBpps || needsDepCheck) {  
  64.             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);  
  65.             if (hasInstAwareBpps) {  
  66.                 for (BeanPostProcessor bp : getBeanPostProcessors()) {  
  67.                     if (bp instanceof InstantiationAwareBeanPostProcessor) {  
  68.                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
  69.                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  
  70.                         if (pvs == null) {  
  71.                             return;  
  72.                         }  
  73.                     }  
  74.                 }  
  75.             }  
  76.             if (needsDepCheck) {  
  77.                 checkDependencies(beanName, mbd, filteredPds, pvs);  
  78.             }  
  79.         }  
  80.   
  81.         applyPropertyValues(beanName, mbd, bw, pvs);  
  82.     }  

 

我真不知道这些代码是怎么写出来的。

怎么能这么牛,有时候看到这些浩如烟海的牛逼的代码,真是觉得自己和人家比起来,技术的道路算是到头了。

这些人真是他妈的天才。

 

 

附:cglib的简单介绍:

http://java.csecs.com/posts/list/1633.html

http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html

http://www.blogjava.net/georgehill/archive/2005/05/24/5126.html

分析Spring源代码之,DI的实现

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
ai 上一节中,我们已经对JdbcDaoSupport和JdbcTemplate有了一定的了解。但是,我们只是初步的了解了
我们首先来看下BeanFacroty接口 package org.springframework.beans.factory; import org.springfra
我们首先来看下BeanFacroty接口; package org.springframework.beans.factory; import org.springf
一、 什么是循环依赖 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引
我们知道,在spring中,配置文件是通过资源形式加载的,我们首先来分析一些在spring中资源类的结构
我们知道,在spring中,配置文件是通过资源形式加载的,我们首先来分析一些在spring中资源类的结构
1.构造方法注入(只需提供一个构造方法) javabean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 packa
IOC(Inversion of Control):其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起
Engine是ES最接近神Lucene的地方,是对Lucene分布式环境访问的一层封装。这个类的接口,是个命令模
Tomcat 源代码分析之ClassLoader 此系列文章皆为Tomcat 7.0代码代码分析。 1. ClassLoader基础知识
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号