Spring之ioc

本来和一个同事说每天都分享点东西的,不过最近遇到点问题,相信他也能理解

这几天也没什么心思分享什么,随便聊聊spring的ioc吧,控制反转,都不陌生,将对象的创建和依赖关系交给容器管理,具体怎么实现的,没心情说太多废话了直接说说重点吧

给出两个类

学生类

[java]  view plain  copy
  1. public class Student {  
  2.   
  3.       
  4.     public void study(){  
  5.         System.out.println("活到老学到老");  
  6.     }  
  7. }  

学校类

[java]  view plain  copy
  1. public class School {  
  2.   
  3.     public Student student;  
  4.   
  5.     public School(Student student) {  
  6.         super();  
  7.         this.student = student;  
  8.     }  
  9.       
  10.     public void study(){  
  11.         student.study();  
  12.     }  
  13. }  
可以看到构造的时候还的自己管理student,如果用ioc呢

[java]  view plain  copy
  1. public class School {  
  2.   
  3.     @Autowired  
  4.     public Student student;  
  5.   
  6.     public void study(){  
  7.         student.study();  
  8.     }  
  9. }  
简单了一些是吧,可能觉得没少几行代码,但是工作中就能真正体现出来它的优势了

这是通过注解的方式实现ioc,也可以通过xml的方法实现,注解方式简明,但是如果修改的话比较麻烦,xml形势修改起来容易,只需要把xml文件修改就可以,但是如果是复杂依赖关系的话xml文件会很臃肿

spring是如何实现ioc的,首先需要看最核心的一个接口BeanFactory

[java]  view plain  copy
  1. /* 
  2.  * Copyright 2002-2011 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.  * @author Chris Beams 
  91.  * @since 13 April 2001 
  92.  * @see BeanNameAware#setBeanName 
  93.  * @see BeanClassLoaderAware#setBeanClassLoader 
  94.  * @see BeanFactoryAware#setBeanFactory 
  95.  * @see org.springframework.context.ResourceLoaderAware#setResourceLoader 
  96.  * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher 
  97.  * @see org.springframework.context.MessageSourceAware#setMessageSource 
  98.  * @see org.springframework.context.ApplicationContextAware#setApplicationContext 
  99.  * @see org.springframework.web.context.ServletContextAware#setServletContext 
  100.  * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization 
  101.  * @see InitializingBean#afterPropertiesSet 
  102.  * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName 
  103.  * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization 
  104.  * @see DisposableBean#destroy 
  105.  * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName 
  106.  */  
  107. public interface BeanFactory {  
  108.   
  109.     /** 
  110.      * Used to dereference a {@link FactoryBean} instance and distinguish it from 
  111.      * beans <i>created</i> by the FactoryBean. For example, if the bean named 
  112.      * <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code> 
  113.      * will return the factory, not the instance returned by the factory. 
  114.      */  
  115.     String FACTORY_BEAN_PREFIX = "&";  
  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.      * {@code 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 definition or externally registered singleton 
  185.      * instance with the given name? 
  186.      * <p>If the given name is an alias, it will be translated back to the corresponding 
  187.      * canonical bean name. 
  188.      * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot 
  189.      * be found in this factory instance. 
  190.      * <p>If a bean definition or singleton instance matching the given name is found, 
  191.      * this method will return {@code true} whether the named bean definition is concrete 
  192.      * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true} 
  193.      * return value from this method does not necessarily indicate that {@link #getBean} 
  194.      * will be able to obtain an instance for the same name. 
  195.      * @param name the name of the bean to query 
  196.      * @return whether a bean with the given name is present 
  197.      */  
  198.     boolean containsBean(String name);  
  199.   
  200.     /** 
  201.      * Is this bean a shared singleton? That is, will {@link #getBean} always 
  202.      * return the same instance? 
  203.      * <p>Note: This method returning <code>false</code> does not clearly indicate 
  204.      * independent instances. It indicates non-singleton instances, which may correspond 
  205.      * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly 
  206.      * check for independent instances. 
  207.      * <p>Translates aliases back to the corresponding canonical bean name. 
  208.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  209.      * @param name the name of the bean to query 
  210.      * @return whether this bean corresponds to a singleton instance 
  211.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  212.      * @see #getBean 
  213.      * @see #isPrototype 
  214.      */  
  215.     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
  216.   
  217.     /** 
  218.      * Is this bean a prototype? That is, will {@link #getBean} always return 
  219.      * independent instances? 
  220.      * <p>Note: This method returning <code>false</code> does not clearly indicate 
  221.      * a singleton object. It indicates non-independent instances, which may correspond 
  222.      * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly 
  223.      * check for a shared singleton instance. 
  224.      * <p>Translates aliases back to the corresponding canonical bean name. 
  225.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  226.      * @param name the name of the bean to query 
  227.      * @return whether this bean will always deliver independent instances 
  228.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  229.      * @since 2.0.3 
  230.      * @see #getBean 
  231.      * @see #isSingleton 
  232.      */  
  233.     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
  234.   
  235.     /** 
  236.      * Check whether the bean with the given name matches the specified type. 
  237.      * More specifically, check whether a {@link #getBean} call for the given name 
  238.      * would return an object that is assignable to the specified target type. 
  239.      * <p>Translates aliases back to the corresponding canonical bean name. 
  240.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  241.      * @param name the name of the bean to query 
  242.      * @param targetType the type to match against 
  243.      * @return <code>true</code> if the bean type matches, 
  244.      * <code>false</code> if it doesn't match or cannot be determined yet 
  245.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  246.      * @since 2.0.1 
  247.      * @see #getBean 
  248.      * @see #getType 
  249.      */  
  250.     boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;  
  251.   
  252.     /** 
  253.      * Determine the type of the bean with the given name. More specifically, 
  254.      * determine the type of object that {@link #getBean} would return for the given name. 
  255.      * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates, 
  256.      * as exposed by {@link FactoryBean#getObjectType()}. 
  257.      * <p>Translates aliases back to the corresponding canonical bean name. 
  258.      * Will ask the parent factory if the bean cannot be found in this factory instance. 
  259.      * @param name the name of the bean to query 
  260.      * @return the type of the bean, or <code>null</code> if not determinable 
  261.      * @throws NoSuchBeanDefinitionException if there is no bean with the given name 
  262.      * @since 1.1.2 
  263.      * @see #getBean 
  264.      * @see #isTypeMatch 
  265.      */  
  266.     Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
  267.   
  268.     /** 
  269.      * Return the aliases for the given bean name, if any. 
  270.      * All of those aliases point to the same bean when used in a {@link #getBean} call. 
  271.      * <p>If the given name is an alias, the corresponding original bean name 
  272.      * and other aliases (if any) will be returned, with the original bean name 
  273.      * being the first element in the array. 
  274.      * <p>Will ask the parent factory if the bean cannot be found in this factory instance. 
  275.      * @param name the bean name to check for aliases 
  276.      * @return the aliases, or an empty array if none 
  277.      * @see #getBean 
  278.      */  
  279.     String[] getAliases(String name);  
  280.   
  281. }  

很长的源码,不过可以明显可以看到有一些getBean方法,通过名字或者通过类型

工厂生产bean至少要知道两件事,1.bean的定义 2.bean之间的依赖,就如同上述的学生类和学校类之间的依赖关系

先来看第一个问题,怎么持有一个bean的定义,这里引入另一个接口BeanDefinition,看下源码

[java]  view plain  copy
  1. /* 
  2.  * Copyright 2002-2011 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 specified factory bean, if any, 
  127.      * or otherwise as a static method on the local bean class. 
  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. }  
它就是定义bean的接口,可以看到它继承了两个原始接口,AttributeAccessor里面有一些get set方法,用于操纵属性,而BeanMetadataElement只有一个方法,getSource用于获取元素,这样已经可以持有bean的定义,再看BeanDefinition中的

[java]  view plain  copy
  1. /** 
  2.      * Return the bean names that this bean depends on. 
  3.      */  
  4.     String[] getDependsOn();  
  5.   
  6.     /** 
  7.      * Set the names of the beans that this bean depends on being initialized. 
  8.      * The bean factory will guarantee that these beans get initialized first. 
  9.      */  
  10.     void setDependsOn(String[] dependsOn);  

用于设置依赖关系,到这基本可以了解了spring实现ioc需要的一些基本接口和方法了

接下来我们就要找到BeanFactory的实现类,看看它是如何生产bean的,这里就不解释怎么找到这个类的了,这个类就是DefaultListableBeanFactory,源码太长了就不贴上了,里面持有了Map<String,BeanDefinition>,可以猜想,通过这个map可以通过name获取到bean的定义和依赖关系了

我们直接写个demo

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">    
  5.  <bean id="student" class="coom.michelle.dream.ioc.Student"></bean>    
  6. </beans>    
再看我们的测试类

[java]  view plain  copy
  1. public class Test{  
  2.      public static void main(String[] args) {    
  3.             ClassPathResource classPathResource = new ClassPathResource("beans.xml");    
  4.             DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();    
  5.             XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);    
  6.             xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);    
  7.             ((Student)defaultListableBeanFactory.getBean("student")).study();;    
  8.         }    
  9.       
  10. }  

打印结果为

八月 03, 2017 7:26:43 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [beans.xml]

活到老学到老


如果之前说的这些原始接口原始类都没有很深的印象,那么这个类大家肯定都知道,ApplicationContext,我们使用这个类生成bean,看下测试类

[java]  view plain  copy
  1. public class Test{  
  2.      public static void main(String[] args) {    
  3.          ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:beans.xml");    
  4.          ((Student)applicationContext.getBean("student")).study();;   
  5.         }    
  6.       
  7. }  

打印结果为

八月 03, 2017 7:29:22 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@b81eda8: startup date [Thu Aug 03 19:29:22 CST 2017]; root of context hierarchy

八月 03, 2017 7:29:23 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [beans.xml]

八月 03, 2017 7:29:23 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons

信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cd8737: defining beans [student]; root of factory hierarchy

活到老学到老


同样的效果,以上对ioc的分析就到这里结束了,希望能对朋友有所帮助,愿明天更美好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值