Spring原始碼學習之路---IOC初探(二)

坦GA發表於2018-04-03

原文地址:https://blog.csdn.net/zuoxiaolong8810/article/details/8550421

          上一章當中我沒有提及具體的搭建環境的步驟,一個是不得不承認有點懶,另外一個我覺得如果上章所述的那些環境都還不會搭建的話,研究spring的原始碼還有些過早。

          如果你有興趣的話,相信已經搭建好了學習研究的環境,接下來就可以進入正題了。

          網上也有很多關於spring原始碼學習的文章以及帖子,講的也都不錯,但是有些可能高估了讀者的能力,該深入的地方反倒一句帶過,我現在也是在一步一步研究,和大家的進度一樣,所以可能在我的角度來和各位探討,更加容易。

          首先我們來說一下IOC,IOC是spring最核心的理念,包括AOP也要屈居第二,那麼IOC到底是什麼呢,四個字,控制反轉。

          網上有不少是這麼解釋IOC的,說IOC是將物件的建立和依賴關係交給容器,這句話我相信不少人都知道,在我個人的理解,IOC就是讓我們的開發變的更簡單了。

          為什麼這麼說呢,光說沒意思,直接上程式碼。

[java] view plain copy
  1.  public class Person {  
  2.   
  3.     public void work(){  
  4.         System.out.println("I am working");  
  5.     }  
  6. }  

         上面這個是Person類,如果我們還有一個Company公司類,公司要開張需要人來工作,所以我們可能需要這樣。

[java] view plain copy
  1. public class Company {  
  2.   
  3.     public Person person;  
  4.       
  5.     public Company(Person person){  
  6.         this.person = person;  
  7.     }  
  8.       
  9.     public void open(){  
  10.         person.work();  
  11.         System.out.println("I am opening");  
  12.     }  
  13. }  

         好了,這樣可以了,雖說和現實有些區別,畢竟沒有一個人的公司,但是就是這麼個意思。必須要有人在公司裡,公司才能開張。

         有了spring上述情況我們是怎麼寫的呢?Person類不變,Company就可以簡單些了。

[java] view plain copy
  1. public class Company {  
  2.   
  3.     @Autowired  
  4.     public Person person;  
  5.       
  6.     public void open(){  
  7.         person.work();  
  8.         System.out.println("I am opening");  
  9.     }  
  10. }  

         OK了,使用註解後,spring裡的寫法是這樣的,是不是簡單很多?或許你可能會說,這才減少了多少程式碼,但是事實上是,真正的專案中,不可能有這麼簡單的依賴關係,或許是2層,3層甚至N層。

         當然,可能我們有時候用的XML,XML和註解的區別就在於這裡,註解可以快速的完成依賴的注入,但是缺點也很明顯,那就是比如我公司裡不需要人了,我需要的是機器,那麼我還要手動改程式碼,將Person換成機器(這裡應該是英文,英語不好,懶得查了,只記得念“磨洗”),而如果是XML配置,那麼我們只需要改下配置檔案就可以。維護起來會方便很多,當然XML的缺點也很明顯,那就是依賴關係複雜的時候,XML檔案會比較臃腫,所以我們一般的做法是將XML分離開來。

         說到這裡,有些扯遠了,但是我覺得以上可以足夠說明IOC的好處,知道了IOC的好處,我們自然就要知道怎麼來實現IOC了。

         或許看了spring的原始碼,第一感覺是很蒙,包太多,我也很蒙,但是研究東西就是得沉下心來,先來關注一下這個介面,BeanFactory,附上程式碼。

[java] view plain copy
  1. /* 
  2.  * Copyright 2002-2010 the original author or authors. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package org.springframework.beans.factory;  
  18.   
  19. import org.springframework.beans.BeansException;  
  20.   
  21. /** 
  22.  * The root interface for accessing a Spring bean container. 
  23.  * This is the basic client view of a bean container; 
  24.  * further interfaces such as {@link ListableBeanFactory} and 
  25.  * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} 
  26.  * are available for specific purposes. 
  27.  * 
  28.  * <p>This interface is implemented by objects that hold a number of bean definitions, 
  29.  * each uniquely identified by a String name. Depending on the bean definition, 
  30.  * the factory will return either an independent instance of a contained object 
  31.  * (the Prototype design pattern), or a single shared instance (a superior 
  32.  * alternative to the Singleton design pattern, in which the instance is a 
  33.  * singleton in the scope of the factory). Which type of instance will be returned 
  34.  * depends on the bean factory configuration: the API is the same. Since Spring 
  35.  * 2.0, further scopes are available depending on the concrete application 
  36.  * context (e.g. "request" and "session" scopes in a web environment). 
  37.  * 
  38.  * <p>The point of this approach is that the BeanFactory is a central registry 
  39.  * of application components, and centralizes configuration of application 
  40.  * components (no more do individual objects need to read properties files, 
  41.  * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and 
  42.  * Development" for a discussion of the benefits of this approach. 
  43.  * 
  44.  * <p>Note that it is generally better to rely on Dependency Injection 
  45.  * ("push" configuration) to configure application objects through setters 
  46.  * or constructors, rather than use any form of "pull" configuration like a 
  47.  * BeanFactory lookup. Spring's Dependency Injection functionality is 
  48.  * implemented using this BeanFactory interface and its subinterfaces. 
  49.  * 
  50.  * <p>Normally a BeanFactory will load bean definitions stored in a configuration 
  51.  * source (such as an XML document), and use the <code>org.springframework.beans</code> 
  52.  * package to configure the beans. However, an implementation could simply return 
  53.  * Java objects it creates as necessary directly in Java code. There are no 
  54.  * constraints on how the definitions could be stored: LDAP, RDBMS, XML, 
  55.  * properties file, etc. Implementations are encouraged to support references 
  56.  * amongst beans (Dependency Injection). 
  57.  * 
  58.  * <p>In contrast to the methods in {@link ListableBeanFactory}, all of the 
  59.  * operations in this interface will also check parent factories if this is a 
  60.  * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance, 
  61.  * the immediate parent factory will be asked. Beans in this factory instance 
  62.  * are supposed to override beans of the same name in any parent factory. 
  63.  * 
  64.  * <p>Bean factory implementations should support the standard bean lifecycle interfaces 
  65.  * as far as possible. The full set of initialization methods and their standard order is:<br> 
  66.  * 1. BeanNameAware's <code>setBeanName</code><br> 
  67.  * 2. BeanClassLoaderAware's <code>setBeanClassLoader</code><br> 
  68.  * 3. BeanFactoryAware's <code>setBeanFactory</code><br> 
  69.  * 4. ResourceLoaderAware's <code>setResourceLoader</code> 
  70.  * (only applicable when running in an application context)<br> 
  71.  * 5. ApplicationEventPublisherAware's <code>setApplicationEventPublisher</code> 
  72.  * (only applicable when running in an application context)<br> 
  73.  * 6. MessageSourceAware's <code>setMessageSource</code> 
  74.  * (only applicable when running in an application context)<br> 
  75.  * 7. ApplicationContextAware's <code>setApplicationContext</code> 
  76.  * (only applicable when running in an application context)<br> 
  77.  * 8. ServletContextAware's <code>setServletContext</code> 
  78.  * (only applicable when running in a web application context)<br> 
  79.  * 9. <code>postProcessBeforeInitialization</code> methods of BeanPostProcessors<br> 
  80.  * 10. InitializingBean's <code>afterPropertiesSet</code><br> 
  81.  * 11. a custom init-method definition<br> 
  82.  * 12. <code>postProcessAfterInitialization</code> methods of BeanPostProcessors 
  83.  * 
  84.  * <p>On shutdown of a bean factory, the following lifecycle methods apply:<br> 
  85.  * 1. DisposableBean's <code>destroy</code><br> 
  86.  * 2. a custom destroy-method definition 
  87.  * 
  88.  * @author Rod Johnson 
  89.  * @author Juergen Hoeller 
  90.  * @since 13 April 2001 
  91.  * @see BeanNameAware#setBeanName 
  92.  * @see BeanClassLoaderAware#setBeanClassLoader 
  93.  * @see BeanFactoryAware#setBeanFactory 
  94.  * @see org.springframework.context.ResourceLoaderAware#setResourceLoader 
  95.  * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher 
  96.  * @see org.springframework.context.MessageSourceAware#setMessageSource 
  97.  * @see org.springframework.context.ApplicationContextAware#setApplicationContext 
  98.  * @see org.springframework.web.context.ServletContextAware#setServletContext 
  99.  * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization 
  100.  * @see InitializingBean#afterPropertiesSet 
  101.  * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName 
  102.  * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization 
  103.  * @see DisposableBean#destroy 
  104.  * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName 
  105.  */  
  106. public interface BeanFactory {  
  107.   
  108.     /** 
  109.      * Used to dereference a {@link FactoryBean} instance and distinguish it from 
  110.      * beans <i>created</i> by the FactoryBean. For example, if the bean named 
  111.      * <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code> 
  112.      * will return the factory, not the instance returned by the factory. 
  113.      */  
  114.     String FACTORY_BEAN_PREFIX = "&";  
  115.   
  116.   
  117.     /** 
  118.      * Return an instance, which may be shared or independent, of the specified bean. 
  119.      * <p>This method allows a Spring BeanFactory to be used as a replacement for the 
  120.      * Singleton or Prototype design pattern. Callers may retain references to 
  121.      * returned objects in the case of Singleton beans. 
  122.      * <p>Translates aliases back to the corresponding canonical bean name. 
  123.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  124.      * @param name the name of the bean to retrieve 
  125.      * @return an instance of the bean 
  126.      * @throws NoSuchBeanDefinitionException if there is no bean definition 
  127.      * with the specified name 
  128.      * @throws BeansException if the bean could not be obtained 
  129.      */  
  130.     Object getBean(String name) throws BeansException;  
  131.   
  132.     /** 
  133.      * Return an instance, which may be shared or independent, of the specified bean. 
  134.      * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type 
  135.      * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the 
  136.      * required type. This means that ClassCastException can't be thrown on casting 
  137.      * the result correctly, as can happen with {@link #getBean(String)}. 
  138.      * <p>Translates aliases back to the corresponding canonical bean name. 
  139.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  140.      * @param name the name of the bean to retrieve 
  141.      * @param requiredType type the bean must match. Can be an interface or superclass 
  142.      * of the actual class, or <code>null</code> for any match. For example, if the value 
  143.      * is <code>Object.class</code>, this method will succeed whatever the class of the 
  144.      * returned instance. 
  145.      * @return an instance of the bean 
  146.      * @throws NoSuchBeanDefinitionException if there's no such bean definition 
  147.      * @throws BeanNotOfRequiredTypeException if the bean is not of the required type 
  148.      * @throws BeansException if the bean could not be created 
  149.      */  
  150.     <T> T getBean(String name, Class<T> requiredType) throws BeansException;  
  151.   
  152.     /** 
  153.      * Return the bean instance that uniquely matches the given object type, if any. 
  154.      * @param requiredType type the bean must match; can be an interface or superclass. 
  155.      * {@literal null} is disallowed. 
  156.      * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory 
  157.      * but may also be translated into a conventional by-name lookup based on the name 
  158.      * of the given type. For more extensive retrieval operations across sets of beans, 
  159.      * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. 
  160.      * @return an instance of the single bean matching the required type 
  161.      * @throws NoSuchBeanDefinitionException if there is not exactly one matching bean found 
  162.      * @since 3.0 
  163.      * @see ListableBeanFactory 
  164.      */  
  165.     <T> T getBean(Class<T> requiredType) throws BeansException;  
  166.   
  167.     /** 
  168.      * Return an instance, which may be shared or independent, of the specified bean. 
  169.      * <p>Allows for specifying explicit constructor arguments / factory method arguments, 
  170.      * overriding the specified default arguments (if any) in the bean definition. 
  171.      * @param name the name of the bean to retrieve 
  172.      * @param args arguments to use if creating a prototype using explicit arguments to a 
  173.      * static factory method. It is invalid to use a non-null args value in any other case. 
  174.      * @return an instance of the bean 
  175.      * @throws NoSuchBeanDefinitionException if there's no such bean definition 
  176.      * @throws BeanDefinitionStoreException if arguments have been given but 
  177.      * the affected bean isn't a prototype 
  178.      * @throws BeansException if the bean could not be created 
  179.      * @since 2.5 
  180.      */  
  181.     Object getBean(String name, Object... args) throws BeansException;  
  182.   
  183.     /** 
  184.      * Does this bean factory contain a bean with the given name? More specifically, 
  185.      * is {@link #getBean} able to obtain a bean instance for the given name? 
  186.      * <p>Translates aliases back to the corresponding canonical bean name. 
  187.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  188.      * @param name the name of the bean to query 
  189.      * @return whether a bean with the given name is defined 
  190.      */  
  191.     boolean containsBean(String name);  
  192.   
  193.     /** 
  194.      * Is this bean a shared singleton? That is, will {@link #getBean} always 
  195.      * return the same instance? 
  196.      * <p>Note: This method returning <code>false</code> does not clearly indicate 
  197.      * independent instances. It indicates non-singleton instances, which may correspond 
  198.      * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly 
  199.      * check for independent instances. 
  200.      * <p>Translates aliases back to the corresponding canonical bean name. 
  201.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  202.      * @param name the name of the bean to query 
  203.      * @return whether this bean corresponds to a singleton instance 
  204.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  205.      * @see #getBean 
  206.      * @see #isPrototype 
  207.      */  
  208.     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
  209.   
  210.     /** 
  211.      * Is this bean a prototype? That is, will {@link #getBean} always return 
  212.      * independent instances? 
  213.      * <p>Note: This method returning <code>false</code> does not clearly indicate 
  214.      * a singleton object. It indicates non-independent instances, which may correspond 
  215.      * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly 
  216.      * check for a shared singleton instance. 
  217.      * <p>Translates aliases back to the corresponding canonical bean name. 
  218.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  219.      * @param name the name of the bean to query 
  220.      * @return whether this bean will always deliver independent instances 
  221.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  222.      * @since 2.0.3 
  223.      * @see #getBean 
  224.      * @see #isSingleton 
  225.      */  
  226.     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
  227.   
  228.     /** 
  229.      * Check whether the bean with the given name matches the specified type. 
  230.      * More specifically, check whether a {@link #getBean} call for the given name 
  231.      * would return an object that is assignable to the specified target type. 
  232.      * <p>Translates aliases back to the corresponding canonical bean name. 
  233.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  234.      * @param name the name of the bean to query 
  235.      * @param targetType the type to match against 
  236.      * @return <code>true</code> if the bean type matches, 
  237.      * <code>false</code> if it doesn't match or cannot be determined yet 
  238.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  239.      * @since 2.0.1 
  240.      * @see #getBean 
  241.      * @see #getType 
  242.      */  
  243.     boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;  
  244.   
  245.     /** 
  246.      * Determine the type of the bean with the given name. More specifically, 
  247.      * determine the type of object that {@link #getBean} would return for the given name. 
  248.      * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates, 
  249.      * as exposed by {@link FactoryBean#getObjectType()}. 
  250.      * <p>Translates aliases back to the corresponding canonical bean name. 
  251.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  252.      * @param name the name of the bean to query 
  253.      * @return the type of the bean, or <code>null</code> if not determinable 
  254.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  255.      * @since 1.1.2 
  256.      * @see #getBean 
  257.      * @see #isTypeMatch 
  258.      */  
  259.     Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
  260.   
  261.     /** 
  262.      * Return the aliases for the given bean name, if any. 
  263.      * All of those aliases point to the same bean when used in a {@link #getBean} call. 
  264.      * <p>If the given name is an alias, the corresponding original bean name 
  265.      * and other aliases (if any) will be returned, with the original bean name 
  266.      * being the first element in the array. 
  267.      * <p>Will ask the parent factory if the bean cannot be found in this factory instance. 
  268.      * @param name the bean name to check for aliases 
  269.      * @return the aliases, or an empty array if none 
  270.      * @see #getBean 
  271.      */  
  272.     String[] getAliases(String name);  
  273.   
  274. }  

          這個便是spring核心的Bean工廠定義,上面的author說是2001年寫的,已經歷史久遠了,這個類是spring中所有bean工廠,也就是俗稱的IOC容器的祖宗,各種IOC容器都只是它的實現或者為了滿足特別需求的擴充套件實現,包括我們平時用的最多的ApplicationContext。從上面的方法就可以看出,這些工廠的實現最大的作用就是根據bean的名稱亦或型別等等,來返回一個bean的例項。

          一個工廠如果想擁有這樣的功能,那麼它一定需要以下幾個因素:

          1.需要持有各種bean的定義,否則無法正確的完成bean的例項化。

          2.需要持有bean之間的依賴關係,否則在bean例項化的過程中也會出現問題。例如上例,如果我們只是各自持有Person和Company,卻不知道他們的依賴關係,那麼在Company初始化以後,呼叫open方法時,就會報空指標。這是因為Company其實並沒有真正的被正確初始化。

          3.以上兩種都要依賴於我們所寫的依賴關係的定義,暫且認為是XML檔案(其實可以是各種各樣的),那麼我們需要一個工具來完成XML檔案的讀取。

          我目前想到的,只需要滿足以上三種條件,便可以建立一個bean工廠,來生產各種bean。當然,spring有更高階的做法,以上只是我們直觀的去想如何實現IOC。

          其實在上述過程中仍舊有一些問題,比如第一步,我們需要持有bean的定義,如何持有?這是一個問題。我們知道spring的XML配置檔案中,有一個屬性是lazy-init,這就說明,bean在何時例項化我們是可以控制的。這個屬性預設是false,但是我們可以將這個屬性設定為true,也就是說spring容器初始化以後,配置了延遲載入的各種bean都還未產生,它們只在需要的時候出現。

          所以我們無法直接的建立一個Map<String,Object>來持有這些bean的例項,在這裡要注意,我們要儲存的是bean的定義,而非例項。

          那麼接下來,又是一個祖宗級別的介面要出現了,來看BeanDefinition。

[java] view plain copy
  1. /* 
  2.  * Copyright 2002-2009 the original author or authors. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package org.springframework.beans.factory.config;  
  18.   
  19. import org.springframework.beans.BeanMetadataElement;  
  20. import org.springframework.beans.MutablePropertyValues;  
  21. import org.springframework.core.AttributeAccessor;  
  22.   
  23. /** 
  24.  * A BeanDefinition describes a bean instance, which has property values, 
  25.  * constructor argument values, and further information supplied by 
  26.  * concrete implementations. 
  27.  * 
  28.  * <p>This is just a minimal interface: The main intention is to allow a 
  29.  * {@link BeanFactoryPostProcessor} such as {@link PropertyPlaceholderConfigurer} 
  30.  * to introspect and modify property values and other bean metadata. 
  31.  * 
  32.  * @author Juergen Hoeller 
  33.  * @author Rob Harrop 
  34.  * @since 19.03.2004 
  35.  * @see ConfigurableListableBeanFactory#getBeanDefinition 
  36.  * @see org.springframework.beans.factory.support.RootBeanDefinition 
  37.  * @see org.springframework.beans.factory.support.ChildBeanDefinition 
  38.  */  
  39. public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {  
  40.   
  41.     /** 
  42.      * Scope identifier for the standard singleton scope: "singleton". 
  43.      * <p>Note that extended bean factories might support further scopes. 
  44.      * @see #setScope 
  45.      */  
  46.     String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;  
  47.   
  48.     /** 
  49.      * Scope identifier for the standard prototype scope: "prototype". 
  50.      * <p>Note that extended bean factories might support further scopes. 
  51.      * @see #setScope 
  52.      */  
  53.     String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;  
  54.   
  55.   
  56.     /** 
  57.      * Role hint indicating that a <code>BeanDefinition</code> is a major part 
  58.      * of the application. Typically corresponds to a user-defined bean. 
  59.      */  
  60.     int ROLE_APPLICATION = 0;  
  61.   
  62.     /** 
  63.      * Role hint indicating that a <code>BeanDefinition</code> is a supporting 
  64.      * part of some larger configuration, typically an outer 
  65.      * {@link org.springframework.beans.factory.parsing.ComponentDefinition}. 
  66.      * <code>SUPPORT</code> beans are considered important enough to be aware 
  67.      * of when looking more closely at a particular 
  68.      * {@link org.springframework.beans.factory.parsing.ComponentDefinition}, 
  69.      * but not when looking at the overall configuration of an application. 
  70.      */  
  71.     int ROLE_SUPPORT = 1;  
  72.   
  73.     /** 
  74.      * Role hint indicating that a <code>BeanDefinition</code> is providing an 
  75.      * entirely background role and has no relevance to the end-user. This hint is 
  76.      * used when registering beans that are completely part of the internal workings 
  77.      * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}. 
  78.      */  
  79.     int ROLE_INFRASTRUCTURE = 2;  
  80.   
  81.   
  82.     /** 
  83.      * Return the name of the parent definition of this bean definition, if any. 
  84.      */  
  85.     String getParentName();  
  86.   
  87.     /** 
  88.      * Set the name of the parent definition of this bean definition, if any. 
  89.      */  
  90.     void setParentName(String parentName);  
  91.   
  92.     /** 
  93.      * Return the current bean class name of this bean definition. 
  94.      * <p>Note that this does not have to be the actual class name used at runtime, in 
  95.      * case of a child definition overriding/inheriting the class name from its parent. 
  96.      * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but 
  97.      * rather only use it for parsing purposes at the individual bean definition level. 
  98.      */  
  99.     String getBeanClassName();  
  100.   
  101.     /** 
  102.      * Override the bean class name of this bean definition. 
  103.      * <p>The class name can be modified during bean factory post-processing, 
  104.      * typically replacing the original class name with a parsed variant of it. 
  105.      */  
  106.     void setBeanClassName(String beanClassName);  
  107.   
  108.     /** 
  109.      * Return the factory bean name, if any. 
  110.      */  
  111.     String getFactoryBeanName();  
  112.   
  113.     /** 
  114.      * Specify the factory bean to use, if any. 
  115.      */  
  116.     void setFactoryBeanName(String factoryBeanName);  
  117.   
  118.     /** 
  119.      * Return a factory method, if any. 
  120.      */  
  121.     String getFactoryMethodName();  
  122.   
  123.     /** 
  124.      * Specify a factory method, if any. This method will be invoked with 
  125.      * constructor arguments, or with no arguments if none are specified. 
  126.      * The method will be invoked on the specifed factory bean, if any, 
  127.      * or as static method on the local bean class else. 
  128.      * @param factoryMethodName static factory method name, 
  129.      * or <code>null</code> if normal constructor creation should be used 
  130.      * @see #getBeanClassName() 
  131.      */  
  132.     void setFactoryMethodName(String factoryMethodName);  
  133.   
  134.     /** 
  135.      * Return the name of the current target scope for this bean, 
  136.      * or <code>null</code> if not known yet. 
  137.      */  
  138.     String getScope();  
  139.   
  140.     /** 
  141.      * Override the target scope of this bean, specifying a new scope name. 
  142.      * @see #SCOPE_SINGLETON 
  143.      * @see #SCOPE_PROTOTYPE 
  144.      */  
  145.     void setScope(String scope);  
  146.   
  147.     /** 
  148.      * Return whether this bean should be lazily initialized, i.e. not 
  149.      * eagerly instantiated on startup. Only applicable to a singleton bean. 
  150.      */  
  151.     boolean isLazyInit();  
  152.   
  153.     /** 
  154.      * Set whether this bean should be lazily initialized. 
  155.      * <p>If <code>false</code>, the bean will get instantiated on startup by bean 
  156.      * factories that perform eager initialization of singletons. 
  157.      */  
  158.     void setLazyInit(boolean lazyInit);  
  159.   
  160.     /** 
  161.      * Return the bean names that this bean depends on. 
  162.      */  
  163.     String[] getDependsOn();  
  164.   
  165.     /** 
  166.      * Set the names of the beans that this bean depends on being initialized. 
  167.      * The bean factory will guarantee that these beans get initialized first. 
  168.      */  
  169.     void setDependsOn(String[] dependsOn);  
  170.   
  171.     /** 
  172.      * Return whether this bean is a candidate for getting autowired into some other bean. 
  173.      */  
  174.     boolean isAutowireCandidate();  
  175.   
  176.     /** 
  177.      * Set whether this bean is a candidate for getting autowired into some other bean. 
  178.      */  
  179.     void setAutowireCandidate(boolean autowireCandidate);  
  180.   
  181.     /** 
  182.      * Return whether this bean is a primary autowire candidate. 
  183.      * If this value is true for exactly one bean among multiple 
  184.      * matching candidates, it will serve as a tie-breaker. 
  185.      */  
  186.     boolean isPrimary();  
  187.   
  188.     /** 
  189.      * Set whether this bean is a primary autowire candidate. 
  190.      * <p>If this value is true for exactly one bean among multiple 
  191.      * matching candidates, it will serve as a tie-breaker. 
  192.      */  
  193.     void setPrimary(boolean primary);  
  194.   
  195.   
  196.     /** 
  197.      * Return the constructor argument values for this bean. 
  198.      * <p>The returned instance can be modified during bean factory post-processing. 
  199.      * @return the ConstructorArgumentValues object (never <code>null</code>) 
  200.      */  
  201.     ConstructorArgumentValues getConstructorArgumentValues();  
  202.   
  203.     /** 
  204.      * Return the property values to be applied to a new instance of the bean. 
  205.      * <p>The returned instance can be modified during bean factory post-processing. 
  206.      * @return the MutablePropertyValues object (never <code>null</code>) 
  207.      */  
  208.     MutablePropertyValues getPropertyValues();  
  209.   
  210.   
  211.     /** 
  212.      * Return whether this a <b>Singleton</b>, with a single, shared instance 
  213.      * returned on all calls. 
  214.      * @see #SCOPE_SINGLETON 
  215.      */  
  216.     boolean isSingleton();  
  217.   
  218.     /** 
  219.      * Return whether this a <b>Prototype</b>, with an independent instance 
  220.      * returned for each call. 
  221.      * @see #SCOPE_PROTOTYPE 
  222.      */  
  223.     boolean isPrototype();  
  224.   
  225.     /** 
  226.      * Return whether this bean is "abstract", that is, not meant to be instantiated. 
  227.      */  
  228.     boolean isAbstract();  
  229.   
  230.     /** 
  231.      * Get the role hint for this <code>BeanDefinition</code>. The role hint 
  232.      * provides tools with an indication of the importance of a particular 
  233.      * <code>BeanDefinition</code>. 
  234.      * @see #ROLE_APPLICATION 
  235.      * @see #ROLE_INFRASTRUCTURE 
  236.      * @see #ROLE_SUPPORT 
  237.      */  
  238.     int getRole();  
  239.   
  240.     /** 
  241.      * Return a human-readable description of this bean definition. 
  242.      */  
  243.     String getDescription();  
  244.   
  245.     /** 
  246.      * Return a description of the resource that this bean definition 
  247.      * came from (for the purpose of showing context in case of errors). 
  248.      */  
  249.     String getResourceDescription();  
  250.   
  251.     /** 
  252.      * Return the originating BeanDefinition, or <code>null</code> if none. 
  253.      * Allows for retrieving the decorated bean definition, if any. 
  254.      * <p>Note that this method returns the immediate originator. Iterate through the 
  255.      * originator chain to find the original BeanDefinition as defined by the user. 
  256.      */  
  257.     BeanDefinition getOriginatingBeanDefinition();  
  258.   
  259. }  

            顧名思義,這個便是spring中的bean定義介面,所以其實我們工廠裡持有的bean定義,就是一堆這個玩意,或者是他的實現類和子介面。這個介面並非直接的祖宗介面,他所繼承的兩個介面一個是core下面的AttributeAccessor,繼承這個介面就以為這我們的bean定義介面同樣具有處理屬性的能力,而另外一個是beans下面的BeanMetadataElement,字面翻譯這個介面就是bean的後設資料元素,它可以獲得bean的配置定義的一個元素。在XML檔案中來說,就是會持有一個bean標籤。

            仔細觀看,能發現beanDefinition中有兩個方法分別是String[] getDependsOn()和void setDependsOn(String[] dependsOn),這兩個方法就是獲取依賴的beanName和設定依賴的beanName,這樣就好辦了,只要我們有一個BeanDefinition,就可以完全的產生一個完整的bean例項。

            今天就先到這裡吧,我也是邊看邊寫的,與其說跟我一起學,其實這個系列的應該叫原始碼學習筆記,更多的還是看到哪裡,寫到哪裡,談不上跟我一起學。

            如果文中有不周到的地方,希望各位儘管指出。


相關文章