Spring 模块的手写分析 
Spring 源码阅读注意事项:try catch 和 do开头的方法 重点阅读
 
BeanFactory 基本的类体系结构。 四级接口继承体系:
BeanFactory 作为一个主接口不继承任何接口,暂且称为一级接口 获取 bean,是否包含bean,是否单例与原型,获取bean类型,bean别名 api 。 
AutowireCapableBeanFactory提供工厂的装配功能 、HierarchicalBeanFactory提供父容器的访问功能 、ListableBeanFactory容器内 bean 实例的枚举功能  3个子接口继承它,进行功能上的增强,这3个子接口称为二级接口。 
ConfigurableBeanFactory 称为三级接口,对二级接口 HierarchicalBeanFactory 进行了再次增强,还继承了一个外来的接口 SingletonBeanRegistry 
ConfigurableListableBeanFactory 是一个更强大的接口,继承了上述所有的接口,四级接口解析,修改bean定义,并初始化单例  
 
接口隔离原则。
抽象类和实现类 
AbstractBeanFactory 作为一个抽象类,实现了三级接口 ConfigurableBeanFactoryAbstractAutowireCapableBeanFactory 同样是抽象类,继承自 AbstractBeanFactory ,并额外实现了二级接口 AutowireCapableBeanFactory 大部分功能。DefaultListableBeanFactory 继承自 AbstractAutowireCapableBeanFactory ,实现了最强大的四级接口 ConfigurableListableBeanFactory ,并实现了一个外来接口 BeanDefinitionRegistry ,它并非抽象类。最后是最强大的 XmlBeanFactory ,继承自 DefaultListableBeanFactory ,重写了一些功能,使自己更强大 
 
为什么要定义这么多层次的接口?ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。
 
BeanFactory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  interface  BeanFactory                          Object getBean (String name)  throws  BeansException ;     <T> T getBean (String name, Class<T> requiredType)  throws  BeansException ;     <T> T getBean (Class<T> requiredType)  throws  BeansException ;     Object getBean (String name, Object... args)  throws  BeansException ;          boolean  containsBean (String name)           boolean  isSingleton (String name)  throws  NoSuchBeanDefinitionException          boolean  isPrototype (String name)  throws  NoSuchBeanDefinitionException          boolean  isTypeMatch (String name, Class<?> targetType)  throws  NoSuchBeanDefinitionException          Class<?> getType(String name) throws  NoSuchBeanDefinitionException;          String[] getAliases(String name); } 
BeanFactory 中只对 IOC 容器的基本行为作了定义,根本不关心 Bean 是如何定义怎样加载的,只关心工厂里得到什么产品对象,至于怎样生产这些对象,这个接口不关心。
ListableBeanFactory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public  interface  ListableBeanFactory  extends  BeanFactory           boolean  containsBeanDefinition (String beanName)           int  getBeanDefinitionCount ()           String[] getBeanDefinitionNames();          String[] getBeanNamesForType(Class<?> type);,          String[] getBeanNamesForType(Class<?> type, boolean  includeNonSingletons, boolean  allowEagerInit);          <T> Map<String, T> getBeansOfType (Class<T> type)  throws  BeansException ;     <T> Map<String, T> getBeansOfType (Class<T> type,) throws  BeansException ;          Map<String, Object> getBeansWithAnnotation (Class<? extends Annotation> annotationType)  throws  BeansException ;          <A extends Annotation> A findAnnotationOnBean (String beanName, Class<A> annotationType)  ; } 
ListableBeanFactory 3个跟BeanDefinition 有关的总体操作,包括 BeanDefinition 的总数、名字的集合、指定类型的名字的集合。
BeanDefinition 是 Spring 中非常重要的一个类,每个 BeanDefinition 实例都包含一个类在 Spring 工厂中的所有属性。
 
两个 getBeanNamesForType 重载方法,根据指定类型(包括子类)获取其对应的所有 Bean 名字
两个 getBeansOfType 重载方法,根据类型(包括子类) 返回指定 Bean 名和 Bean 的Map
2个跟注解查找有关的方法,根据注解类型,查找 Bean 名和 Bean 的 Map,根据指定 Bean 名和注解类型查找指定 Bean
 
这个工厂的最大特点就是可以列出工厂可以生产的所有实例。工厂并不能直接生产,但是可以返回指定类型的所有实例。
HierarchicalBeanFactory 分层的Bean工厂
1 2 3 4 5 6 public  interface  HierarchicalBeanFactory  extends  BeanFactory           BeanFactory getParentBeanFactory ()  ;          boolean  containsLocalBean (String name)  } 
第一个方法返回 Bean 工厂的父工厂,这个方法实现了工厂的分级
AutowireCapableBeanFactory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public  interface  AutowireCapableBeanFactory  extends  BeanFactory  	 	int  AUTOWIRE_NO = 0 ; 	 	int  AUTOWIRE_BY_NAME = 1 ; 	 	int  AUTOWIRE_BY_TYPE = 2 ; 	 	int  AUTOWIRE_CONSTRUCTOR = 3 ; 	 	<T> T createBean (Class<T> beanClass)  throws  BeansException ; 	 	void  autowireBean (Object existingBean)  throws  BeansException 	 	Object configureBean (Object existingBean, String beanName)  throws  BeansException ; 	 	 	Object createBean (Class<?> beanClass, int  autowireMode, boolean  dependencyCheck)  throws  BeansException ; 	 	Object autowire (Class<?> beanClass, int  autowireMode, boolean  dependencyCheck)  throws  BeansException ; 	 	void  autowireBeanProperties (Object existingBean, int  autowireMode, boolean  dependencyCheck)  			throws  BeansException ;	 	void  applyBeanPropertyValues (Object existingBean, String beanName)  throws  BeansException 	 	Object initializeBean (Object existingBean, String beanName)  throws  BeansException ; 	 	Object applyBeanPostProcessorsBeforeInitialization (Object existingBean, String beanName)   			throws  BeansException ;	 	Object applyBeanPostProcessorsAfterInitialization (Object existingBean, String beanName)   			throws  BeansException ;	void  destroyBean (Object existingBean)  	<T> NamedBeanHolder<T> resolveNamedBean (Class<T> requiredType)  throws  BeansException ; 	 	@Nullable  	Object resolveDependency (DependencyDescriptor descriptor, @Nullable String requestingBeanName)  throws  BeansException ; 	 	@Nullable  	Object resolveDependency (DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)  throws  BeansException ; } 
5个静态不可变常量指明装配策略。8个跟自动装配有关的方法,2个执行 BeanPostProcessors 方法,2个分解指定依赖的方法。
根据定义 BeanDefinition 装配 Bean。执行前、后处理器等。
 
ConfigurableBeanFactory 复杂的配置Bean工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 public  interface  ConfigurableBeanFactory  extends  HierarchicalBeanFactory , SingletonBeanRegistry  	String SCOPE_SINGLETON = "singleton" ; 	String SCOPE_PROTOTYPE = "prototype" ; 	 	void  setParentBeanFactory (BeanFactory parentBeanFactory)  throws  IllegalStateException 	 	void  setBeanClassLoader (@Nullable ClassLoader beanClassLoader)  	@Nullable  	ClassLoader getBeanClassLoader ()  ; 	 	void  setTempClassLoader (@Nullable ClassLoader tempClassLoader)  	@Nullable  	ClassLoader getTempClassLoader ()  ; 	 	void  setCacheBeanMetadata (boolean  cacheBeanMetadata)  	 	boolean  isCacheBeanMetadata ()  	 	void  setBeanExpressionResolver (@Nullable BeanExpressionResolver resolver)  	@Nullable  	BeanExpressionResolver getBeanExpressionResolver ()  ; 	 	void  setConversionService (@Nullable ConversionService conversionService)  	@Nullable  	ConversionService getConversionService ()  ; 	 	void  addPropertyEditorRegistrar (PropertyEditorRegistrar registrar)  	 	void  registerCustomEditor (Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass)  	 	void  copyRegisteredEditorsTo (PropertyEditorRegistry registry)  	 	void  setTypeConverter (TypeConverter typeConverter)  	TypeConverter getTypeConverter ()  ; 	 	void  addEmbeddedValueResolver (StringValueResolver valueResolver)  	boolean  hasEmbeddedValueResolver ()  	 	@Nullable  	String resolveEmbeddedValue (String value)  ; 	 	void  addBeanPostProcessor (BeanPostProcessor beanPostProcessor)  	 	int  getBeanPostProcessorCount ()  	 	void  registerScope (String scopeName, Scope scope)  	 	String[] getRegisteredScopeNames(); 	 	@Nullable  	Scope getRegisteredScope (String scopeName)  ; 	 	AccessControlContext getAccessControlContext ()  ; 	 	void  copyConfigurationFrom (ConfigurableBeanFactory otherFactory)  	 	void  registerAlias (String beanName, String alias)  throws  BeanDefinitionStoreException 	 	void  resolveAliases (StringValueResolver valueResolver)  	 	BeanDefinition getMergedBeanDefinition (String beanName)  throws  NoSuchBeanDefinitionException ; 	 	boolean  isFactoryBean (String name)  throws  NoSuchBeanDefinitionException 	 	void  setCurrentlyInCreation (String beanName, boolean  inCreation)  	 	boolean  isCurrentlyInCreation (String beanName)  	 	void  registerDependentBean (String beanName, String dependentBeanName)  	 	String[] getDependentBeans(String beanName); 	 	String[] getDependenciesForBean(String beanName); 	 	void  destroyBean (String beanName, Object beanInstance)  	 	void  destroyScopedBean (String beanName)  	 	void  destroySingletons ()  } 
ConfigurableListableBeanFactory BeanFactory的集大成者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  interface  ConfigurableListableBeanFactory 		extends  ListableBeanFactory , AutowireCapableBeanFactory , ConfigurableBeanFactory   {	void  ignoreDependencyType (Class<?> type)  	void  ignoreDependencyInterface (Class<?> ifc)  	void  registerResolvableDependency (Class<?> dependencyType, @Nullable Object autowiredValue)  	boolean  isAutowireCandidate (String beanName, DependencyDescriptor descriptor)  			throws  NoSuchBeanDefinitionException ; 	 	BeanDefinition getBeanDefinition (String beanName)  throws  NoSuchBeanDefinitionException ; 	Iterator<String> getBeanNamesIterator ()  ; 	void  clearMetadataCache ()  	 	void  freezeConfiguration ()  	 	 	boolean  isConfigurationFrozen ()  	 	void  preInstantiateSingletons ()  throws  BeansException } 
工厂接口 ConfigurableListableBeanFactory 同时继承了3个接口, ListableBeanFactory 、AutowireCapableBeanFactory 和 ConfigurableBeanFactory ,扩展之后,加上自有的这8个方法,这个工厂接口总共有83个方法,实在是巨大到不行了。这个工厂接口的自有方法总体上只是对父类接口功能的补 充,包含了 BeanFactory 体系目前的所有方法,可以说是接口的集大成者。
BeanDefinition 
手写 IOC 框架思路 
读取配置文件的 bean 信息 
将 bean 信息封装到 BeanDefinition 集合对象中 
根据传递过来的 beanName 参数去 BeanDefinition 集合中查找对应的 BeanDefinition 信息 
根据 BeanDefinition 中的信息去创建 Bean 的实例。
a.根据 class 信息包括里面的 constructor-arg 通过反射进行实例化 
b.根据 BeanDefinition 中封装的属性信息集合去挨个给对象赋值 
c.根据 initMethod 方法区调用对象的初始化操作 
 
 
 
如果 singletonObjects 中已经包含了我们要找的对象,就不需要再创建了。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public  class  BeanFactory  	Map<String, BeanDefination> beanDefinations = new  HashMap<>; 	Map<String, Object> singletonObjects = new  HashMap<>(); 	 	BeanFactory() { 		 		 			 		 	} 	 	public  static  Object getBean (String name)   		 		 		 		 		 				 				 				 	} } 
实现 在阅读源码时,需要抓住主线,在手写框架时也一样,先写使用。再写实现
pom.xml中引入自己的框架
1 2 3 4 5 <dependency >     <groupId > cn.lizhaoloveit</groupId >      <artifactId > spring-framework-custom</artifactId >      <version > 1.0</version >  </dependency > 
bean.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <beans > 	<bean  id ="student"  class ="cn.lizhaoloveit.spring.po.Student"  init-method ="initMethod" >  		 		<property  name ="name"  value ="zengkeyan" > </property >  		 		<property  name ="course"  ref ="course" > </property >  	</bean >  	 	<bean  id ="course"  class ="cn.lizhaoloveit.spring.po.Course"   		init-method ="init" > 		 		<property  name ="name"  value ="spring" > </property >  		 		<property  name ="age"  value ="18" > </property >  	</bean >  </beans > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public  class  Student  	private  String name; 	private  Course course; 	public  void  initMethod ()   		System.out.println("初始化方法" ); 	} 	public  void  destroyMethod ()   		System.out.println("销毁方法" ); 	} } public  class  Course  	private  String name; 	private  Integer age; 	public  void  init ()   		System.out.println("我是对象初始化方法" ); 	} } @Test public  void  test ()      String location = "classpath:beans.xml" ;          BeanFactory beanFactory = new  DefaultListableBeanFactory(location);          Student student = beanFactory.getBeans(Student.class);          Student student1 = (Student) beanFactory.getBeans("student" );          System.out.println(student);     System.out.println(student1); } 我是对象初始化方法 初始化方法 初始化方法 Student(name=zengkeyan, course=Course(name=spring, age=18 )) Student(name=zengkeyan, course=Course(name=spring, age=18 )) 
初始化工厂 beanFactory 根据源码分析,先定义顶层逻辑:
BeanFactory
1 2 3 4 public  interface  BeanFactory      Object getBeans (String beanName)  ;     <T> T getBeans (Class<T> clazz)  ; } 
根据分析,为了避免循环引用导致对象创建失败,我们需要先将xml中的文本中的信息封装在BeanDefinition类中。
1 2 3 4 5 6 7 8 9 10 11 12 13 public  class  BeanDefinition      private  String beanName;             private  String beanClassName;        private  String initMethod;           private  List<PropertyValue> propertyValues = new  ArrayList<>();      public  BeanDefinition (String clzName, String beanName)           this .beanClassName = clzName;         this .beanName = beanName;     }     public  void  addPropertyValue (PropertyValue propertyValue)           propertyValues.add(propertyValue);     } } 
抽象类:AbstractBeanFactory,完成其他实现方便扩展。拆分接口,使其可以有更多的功能拆分,结构更明确。
1 2 3 4 5 6 7 8 9 10 11 12 public  abstract  class  AbstractBeanFactory  implements  BeanFactory      @Override      public  <T> T getBeans (Class<T> clazz)   {         return  null ;     }     @Override      public  Object getBeans (String beanName)           return  null ;     }     public  abstract  void  registerBeanDefinition (String beanName, BeanDefinition beanDefinition)      public  abstract  void  registerBeanDefinitionClz (String simpleName, BeanDefinition beanDefinition)  } 
new DefaultListableBeanFactory(location);根据 location 初始化beanFactory。
1 2 3 4 5 6 7 8 9 10 11 public  DefaultListableBeanFactory (String location)           registResource();          registConverters();          Resource resource = getResource(location);          XmlBeanDefinitionParser parser = new  XmlBeanDefinitionParser();     parser.loadBeanDefinations(this , resource); } 
Resource 接口用于根据不同的方式来获取资源
1 2 3 4 public  interface  Resource      boolean  isCanRead (String location)      InputStream getInputStream ()  ; } 
实现类 ClassPathResource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public  class  ClassPathResource  implements  Resource      private  String location;     @Override      public  boolean  isCanRead (String location)           if  (location == null  || "" .equals(location)) {             return  false ;         }         if  (location.startsWith("classpath:" )) {             this .location = location;             return  true ;         }         return  false ;     }     @Override      public  InputStream getInputStream ()           if  (location == null  || "" .equals(location)) return  null ;         String replace = location.replace("classpath:" , "" );         return  this .getClass().getClassLoader().getResourceAsStream(replace);     } } 
将资源实现类,加入 DefaultListableBeanFactory 的资源列表,如果有更多途经,可以添加更多的类,本着对修改关闭,对扩展开放的开闭原则。
1 2 3 private  void  registResource ()      resources.add(new  ClassPathResource()); } 
拿到资源流后,根据资源创建 BeanDefinitions,此时需要一个解析器,将xml中的内容解析为 BeanDefinition 对象。
1 2 3 4 5 6 7 8 9 public  class  XmlBeanDefinitionParser      public  void  loadBeanDefinations (DefaultListableBeanFactory beanFactory, Resource resource)                    InputStream inputStream = resource.getInputStream();         Document document = DocumentReader.createDocument(inputStream);         XmlBeanDefinitionDocumentReader reader = new  XmlBeanDefinitionDocumentReader(beanFactory);         reader.loadBeanDefinitions(document.getRootElement());     } } 
在每一处有可能有扩展的地方,使用面向对象的思想,XmlBeanDefinitionDocumentReader专门解析 Document。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 public  class  XmlBeanDefinitionDocumentReader      private  DefaultListableBeanFactory beanFactory;     public  XmlBeanDefinitionDocumentReader (DefaultListableBeanFactory beanFactory)           this .beanFactory = beanFactory;     }     public  void  loadBeanDefinitions (Element rootElement)           List<Element> elements = rootElement.elements();         for  (Element element : elements) {                          String name = element.getName();                          if  (name.equals("bean" )) {                 parseBeansElement(element);             } else  {                 parseCustomElement(element);             }         }                                                                                                        }          private  void  parseBeansElement (Element element)           if  (element == null ) return ;         try  {                          String id = element.attributeValue("id" );             String name = element.attributeValue("name" );             String clzName = element.attributeValue("class" );             Class<?> clzType = Class.forName(clzName);             String initMethod = element.attributeValue("init-method" );                          String beanName = id == null  ? name : id;             beanName = beanName == null  ? clzType.getSimpleName() : beanName;             BeanDefinition beanDefinition = new  BeanDefinition(clzName, beanName);             beanDefinition.setInitMethod(initMethod);                          List<Element> propertyElements = element.elements();             for  (Element propertyElement : propertyElements) {                 parsePropertyElement(beanDefinition, propertyElement);             }                          registerBeanDefinition(beanName, beanDefinition);             registerBeanDefinitionClass(clzType.getSimpleName(), beanDefinition);         } catch  (ClassNotFoundException e) {             e.printStackTrace();         }     }     private  void  parsePropertyElement (BeanDefinition beanDefinition, Element propertyElement)           if  (propertyElement == null ) return ;                  String name = propertyElement.attributeValue("name" );         String value = propertyElement.attributeValue("value" );         String ref = propertyElement.attributeValue("ref" );         if  (value != null  && !value.equals("" ) && ref != null  && !ref.equals("" )) return ;         PropertyValue propertyValue = null ;         if  (value != null  && !value.equals("" )) {                          Class<?> classType = ReflectUtils.getTypeByFieldName(beanDefinition.getBeanClassName(), name);             TypeStringValue typeStringValue = new  TypeStringValue(value, classType);             propertyValue = new  PropertyValue(name, typeStringValue);             beanDefinition.addPropertyValue(propertyValue);         } else  if  (ref != null  && !ref.equals("" )) {             RuntimeBeanReference reference = new  RuntimeBeanReference(ref);             propertyValue = new  PropertyValue(name, reference);             beanDefinition.addPropertyValue(propertyValue);         } else  return ;     }     private  void  parseCustomElement (Element element)       }     private  void  registerBeanDefinitionClass (String simpleName, BeanDefinition beanDefinition)           this .beanFactory.registerBeanDefinitionClz(simpleName, beanDefinition);     }     private  void  registerBeanDefinition (String beanName, BeanDefinition beanDefinition)           this .beanFactory.registerBeanDefinition(beanName, beanDefinition);     } } ```  解析的过程实际上就是把xml中的Bean标签中的内容填给 BeanDefinition 对象。 值得一说的是 `property` 标签的解析,因为 property 可能有引用类型和数值类型的值。因此在赋值时,需要将两种类型分别创建对象 ```java public  class  PropertyValue      private  String name;     private  Object value; } public  class  TypeStringValue      private  String value;     private  Class<?> classType; } public  class  RuntimeBeanReference      private  String ref; } 
以上,初始化的过程就完结了。
取值 取值的过程实际上就是把 BeanDefinition 中的信息通过反射创建对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 @Override public  Object getBeans (String beanName)      Object instance = singletonObjects.get(beanName);     if  (instance != null ) return  instance;          BeanDefinition beanDefinition = getBeanDefinitionIds().get(beanName);     String beanClassName = beanDefinition.getBeanClassName();     instance = createBeanInstance(beanClassName, null );     setProperty(instance, beanDefinition);     initBean(instance, beanDefinition);     singletonObjects.put(beanName, instance);     return  instance; } @Override public  <T> T getBeans (Class<T> clazz)   {                   String clazzSimpleName = clazz.getSimpleName();     T instance = (T) singletonObjects.get(clazzSimpleName);     if  (instance != null ) return  instance;          BeanDefinition beanDefinition = getBeanDefinitionClzs().get(clazzSimpleName);          String beanClassName = beanDefinition.getBeanClassName();          instance = (T) createBeanInstance(beanClassName, null );                         setProperty(instance, beanDefinition);          initBean(instance, beanDefinition);     singletonObjects.put(clazzSimpleName, instance);     return  instance; } private  <T> void  initBean (T instance, BeanDefinition beanDefinition)      String initMethod = beanDefinition.getInitMethod();     if  (initMethod == null  || initMethod.equals("" )) return ;     ReflectUtils.invokeMethod(instance, initMethod, null ); } private  <T> void  setProperty (T instance, BeanDefinition beanDefinition)      List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();     for  (PropertyValue propertyValue : propertyValues) {         String name = propertyValue.getName();         Object value = propertyValue.getValue();         Object trueValue = null ;         if  (value instanceof  TypeStringValue) {             TypeStringValue typeStringValue = (TypeStringValue) value;             String stringValue = typeStringValue.getValue();             Class<?> clazz = typeStringValue.getClassType();                          for  (TypeConverter typeConverter : typeConverters) {                 if  (typeConverter.isType(clazz)) {                     trueValue = typeConverter.convert(stringValue);                 }             }         } else  if  (value instanceof  RuntimeBeanReference) {             RuntimeBeanReference reference = (RuntimeBeanReference) value;             String ref = reference.getRef();             trueValue = getBeans(ref);         }                  ReflectUtils.setProperty(instance, name, trueValue);     } } private  Object createBeanInstance (String beanClassName, Object... args)      return  ReflectUtils.createObject(beanClassName, args); } ```  需要说明的是,在给属性 property 赋值时,如果值类型为数据类型,则需要进行类型转换,将字符串转换成对应的数据类型。这里就需要用到类型转换器,`TypeConverter` 的作用就是识别类型并且将字符串类型的数据转换为其他数据类型。 ```java public  interface  TypeConverter      boolean  isType (Class<?> clazz)      Object convert (String source)  ; } public  class  IntegerTypeConverter  implements  TypeConverter  	@Override  	public  Integer convert (String source)   		return  Integer.parseInt(source); 	} 	@Override  	public  boolean  isType (Class<?> clazz)   		return  clazz == Integer.class; 	} } public  class  StringTypeConverter  implements  TypeConverter  	@Override  	public  boolean  isType (Class<?> clazz)   		return  clazz == String.class; 	} 	@Override  	public  String convert (String source)   		return  source; 	} } 
以上代码还用到了两个工具类,将反射的操作进行了封装,封装了 dom4j 的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public  class  DocumentReader      public  static  Document createDocument (InputStream inputStream)           Document document = null ;         SAXReader reader = new  SAXReader();         try  {             document = reader.read(inputStream);         } catch  (DocumentException e) {             e.printStackTrace();         }         return  document;     } } public  class  ReflectUtils  	public  static  Object createObject (String beanClassName, Object... args)   		try  { 			Class<?> clazz = Class.forName(beanClassName); 			Constructor<?> constructor = clazz.getConstructor(); 			 			return  constructor.newInstance(args); 		} catch  (Exception e) { 			e.printStackTrace(); 		} 		return  null ; 	} 	public  static  void  setProperty (Object beanInstance, String name, Object value)   		try  { 			Class<?> clazz = beanInstance.getClass(); 			Field field = clazz.getDeclaredField(name); 			field.setAccessible(true ); 			field.set(beanInstance, value); 		} catch  (Exception e) { 			e.printStackTrace(); 		} 	} 	public  static  Class<?> getTypeByFieldName(String beanClassName, String name) { 		try  { 			Class<?> clazz = Class.forName(beanClassName); 			Field field = clazz.getDeclaredField(name); 			return  field.getType(); 		} catch  (Exception e) { 			e.printStackTrace(); 		} 		return  null ; 	} 	public  static  void  invokeMethod (Object beanInstance, String initMethod, Object... args)   		try  { 			Class<?> clazz = beanInstance.getClass(); 			Method method = clazz.getDeclaredMethod(initMethod); 			method.setAccessible(true ); 			method.invoke(beanInstance, args); 		} catch  (Exception e) { 			e.printStackTrace(); 		} 	} } 
至此就是想了 spring 中的 IOC 功能。
SpringIoc源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 @Override public  void  refresh ()  throws  BeansException, IllegalStateException 	synchronized  (this .startupShutdownMonitor) { 		          		prepareRefresh(); 		                                     		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 		          		prepareBeanFactory(beanFactory); 		try  { 			              			postProcessBeanFactory(beanFactory); 			 			             invokeBeanFactoryPostProcessors(beanFactory); 			 			             registerBeanPostProcessors(beanFactory); 			 			             initMessageSource(); 			 			             initApplicationEventMulticaster(); 			 			             onRefresh(); 			 			             registerListeners(); 			 			                          finishBeanFactoryInitialization(beanFactory); 			 			             finishRefresh(); 		} 		catch  (BeansException ex) { 			if  (logger.isWarnEnabled()) { 				logger.warn("Exception encountered during context initialization - "  + 						"cancelling refresh attempt: "  + ex); 			} 			 			destroyBeans(); 			 			cancelRefresh(ex); 			 			throw  ex; 		} 		finally  { 			 			 			resetCommonCaches(); 		} 	} } 
AbstractApplicationContext#refresh: 刷新 spring 容器(删除原有容器,创建新容器)
refresh 里面12个步骤,和IoC相关的是:step2  和  step11,在初始化时一次性创建所有单例
obtainFreshBeanFactory
refreshBeanFactory() 创建 BeanFactory 对象(DefaultListableBeanFactory) 加载 bean信息 
 
 
 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 protected  final  void  refreshBeanFactory ()  throws  BeansException 	 	if  (hasBeanFactory()) { 		destroyBeans(); 		closeBeanFactory(); 	} 	try  {    		 		DefaultListableBeanFactory beanFactory = createBeanFactory(); 		beanFactory.setSerializationId(getId()); 		 		customizeBeanFactory(beanFactory);          		loadBeanDefinitions(beanFactory); 		synchronized  (this .beanFactoryMonitor) { 			this .beanFactory = beanFactory; 		} 	} 	catch  (IOException ex) { 		throw  new  ApplicationContextException("I/O error parsing bean definition source for "  + getDisplayName(), ex); 	} } 
这里用到里模板方法,具体的加载方法在子类中实现。将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
从子类 AbstractRefreshableApplicationContext.java 开始就加载 beanDefinition。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public  int  loadBeanDefinitions (EncodedResource encodedResource)  throws  BeanDefinitionStoreException 	Assert.notNull(encodedResource, "EncodedResource must not be null" ); 	if  (logger.isInfoEnabled()) { 		logger.info("Loading XML bean definitions from "  + encodedResource.getResource()); 	} 	Set<EncodedResource> currentResources = this .resourcesCurrentlyBeingLoaded.get(); 	if  (currentResources == null ) { 		currentResources = new  HashSet<>(4 ); 		this .resourcesCurrentlyBeingLoaded.set(currentResources); 	} 	if  (!currentResources.add(encodedResource)) { 		throw  new  BeanDefinitionStoreException( 				"Detected cyclic loading of "  + encodedResource + " - check your import definitions!" ); 	} 	try  { 		 		InputStream inputStream = encodedResource.getResource().getInputStream(); 		try  { 			 			InputSource inputSource = new  InputSource(inputStream); 			if  (encodedResource.getEncoding() != null ) { 				inputSource.setEncoding(encodedResource.getEncoding()); 			} 			 			return  doLoadBeanDefinitions(inputSource, encodedResource.getResource()); 		} 		finally  { 			inputStream.close(); 		} 	} 	catch  (IOException ex) { 		throw  new  BeanDefinitionStoreException( 				"IOException parsing XML document from "  + encodedResource.getResource(), ex); 	} 	finally  { 		currentResources.remove(encodedResource); 		if  (currentResources.isEmpty()) { 			this .resourcesCurrentlyBeingLoaded.remove(); 		} 	} } 
doLoadBeanDefinitions 方法做具体工作,之前的步骤在堆 resource 进行编码工作。然后调用了下面的方法
registerBeanDefinitions(document, resource) 
 
DefaultBeanDefinitionDocumentReader#registerBeanDefinition 中 调用doRegisterBeanDefinitions注册。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 protected  void  doRegisterBeanDefinitions (Element root)  	 	 	 	 	 	 	 	 	BeanDefinitionParserDelegate parent = this .delegate; 	this .delegate = createDelegate(getReaderContext(), root, parent); 	 	if  (this .delegate.isDefaultNamespace(root)) { 		String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); 		if  (StringUtils.hasText(profileSpec)) { 			String[] specifiedProfiles = StringUtils.tokenizeToStringArray( 					profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); 			if  (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { 				if  (logger.isInfoEnabled()) { 					logger.info("Skipped XML bean definition file due to specified profiles ["  + profileSpec + 							"] not matching: "  + getReaderContext().getResource()); 				} 				return ; 			} 		} 	} 	 	preProcessXml(root); 	 	parseBeanDefinitions(root, this .delegate); 	 	postProcessXml(root); 	this .delegate = parent; } 
parseBeanDefinitions 从根标签开始解析。然后 parseDefaultElement 解析 bean 标签等默认子标签。
processBeanDefinition 解析Bean标签,初始化。还有其他子标签。分情况解析。
BeanDefinitionParserDelegate#parseBeanDefinitionElement 委托 BeanDefinitionParserDelegate 解析。创建 beanDefinition 信息。
循环依赖问题 Spring 中循环依赖的场景
构造器的循环依赖,无法解决,只能将其转变为setter的循环依赖。 
 
解决方案:通过递归方法找出当前 Bean 所依赖的 Bean,然后提前缓存放入cache中,通过提前暴露,exposedObject 用于返回提前暴露的 bean。
Spring 先将 bean 对象实例化(依赖无参构造器),再设置对象属性。Spring 先用构造器实例化 Bean 对象,将实例化结束的对象放到一个 Map 中,并且 Spring 提供获取这个未设置属性的对象的引用方法。如果 A 对象 引用B 对象,会直接从 Map 中获取 B 对象。就不会出现循环问题了。
三级缓存分别指:
singletonFactories 
earlySingletonObjects : 提前曝光的的单例对象的 Cache 用于检测循环引用,与 singletonFactories 互斥 
singletonObject 单例对象的 Cache。 
 
在创建 bean 的时候,首先想到的是从 cache 中获取这个单例的 bean,如果对象为空或者正在创建中,(如果A在创建中依赖了B,就得先创建B,A就在处于创建中状态),Spring 首先从一级缓存 singletonObjects 中获取,如果获取不到,并且对象正在创建,就再从二级缓存 earlySingletonObjects 中获取,如果还是取不到,则从 三级缓存 singletonFactory.getObject 获取,如果取到了,就将该对象从三级缓存中删除,移入二级缓存中
1 this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName);
创建对象三步:
实例化对象,将当前的 beanName 和 一个 ObjectFactory 存储到三级缓存中,ObjectFactory 中的工作就是将第一步创建的空对象提前暴露 
填充属性,填充属性B 需要先创建 B 对象,创建B对象,又需要A对象的属性注入(A 对象不会重新创建,而是从一二三级缓存中去取A对象,此时A对象在三级缓存中) 
初始化对象。 
 
总结 ClassPathXmlApplicationContext:可能是 ClassPath 也可能是 Context
不同的部分用不同的面向对象,相同的部分用共同对象,比如不管是从 Context 中还是 ClassPath 中创建 Context 创建时的部分是一样的。
AbstractBeanDefinitionReader
DefaultBeanDefinitionReader
BeanDefinitionParserDelegate 具体解析 Bean 标签成 BeanDefinition 对象是由该对象完成。
为什么 XmlBeanDefinitionReader 要继承 AbstractBeanDefinitionReader?
 
因为 AbstractXmlApplicationContext 想找阅读器,肯定是找一个通用的阅读器。具体阅读功能的实现是根据不同的情况来由子类实现。