SpringBean的幾個問題以及原理

1、幾個問題

  1. Spring中的bean是如何生成?
  2. Spring提供了哪些擴展點能夠整合第三方框架
  3. Spring如何整合Mybatis的

2、什麼是Spring

Spring管理bean(Java中的對象),初始化的操做,java

3、Spring IoC容器

  1. 資源組件:

    Resource,對資源文件的描述,不一樣資源文件如xml、properties文件等,格式不一樣,最終都將被ResourceLoader加載得到相應的Resource對象;我的理解是。主配置文件.主配置做爲全部配置的入口spring

  2. 資源加載組件:

    ResourceLoader:加載xml、properties等各種格式文件,解析文件,並生成Resource對象。加載哪些解析過的配置資源數據結構

  3. Bean容器組件:

    BeanFactory體系:IoC容器的核心,其餘組件都是爲它工做的(但不是僅僅爲其服務).核心框架

  4. Bean註冊組件:

    SingletonBeanRegister/AliasRegister:將BeanDefinition對象註冊到BeanFactory(BeanDefinition Map)中去。註冊對象所使用的容器dom

  5. Bean描述組件:

    BeanDefinition體系,Spring內部對Bean描述的基本數據結構。負責描述BeanDefinition資源 將資源形式的bean轉化爲spring所指望的格式結構ide

  6. Bean構造組件:

    BeanDefinitionReader體系,讀取Resource並將其數據轉換成一個個BeanDefinition對象。負責將一個個的資源 解析轉化爲BeanDefinition 爲以後描述bean作準備測試

<img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gg9jtxriloj31330mi0w2.jpg" alt="image-20200205095809050" style="zoom:50%;float:left" />this

4、BeanFactory

4.1 準備
  • bean-v1.xml配置bean的信息
  • BeanDefinition用於存放bean的定義
  • BeanFactory獲取bean的信息,實例化bean`
  • BeanFactoryTest測試BeanFactory是否可用
4.2 代碼實現
  1. bean-v1.xmlcode

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
        <bean id="user" class="com.timwang.spring.small.User"/>
        <bean id="invalidBean" class="xxx.xxx"/>
    </beans>
  2. BeanDefinitionxml

    bean-v1.xml中定義了每一個bean,但這些信息咱們該如何存儲呢? spring是經過BeanDefinition接口來描述bean的定義

    package com.timwang.spring.small;
    
    /**
     * @author wangjun
*/

public interface BeanDefinition {

/**
    * 獲取bean.xml中 bean的全名 如 "com.niocoder.service.v1.NioCoderService"
    * @return string
    */
   String getBeanClassName();

}

`GenericBeanDefinition`實現了`BeanDefinition`接口

package com.timwang.spring.small;

/**

* @author wangjun
* @date 2020-06-29
*/

public class GenericBeanDefinition implements BeanDefinition {

private String id;
   private String beanClassName;

   public GenericBeanDefinition(String id, String beanClassName) {
       this.id = id;
       this.beanClassName = beanClassName;
   }

   @Override
   public String getBeanClassName() {
       return this.beanClassName;
   }

   public String getId() {
       return id;
   }

}

3. BeanFactory

咱們已經使用`BeanDefinition`來描述`bean-v1.xml`的`bean`的定義,下面咱們使用`BeanFactory`來獲取`bean`的實例

package com.timwang.spring.small;

/**

* 建立bean的實例
* @author wangjun
* @date 2020-06-29
*/

public interface BeanFactory {

/**
    * 獲取bean的定義
    * @param beanId beanId
    * @return BeanDefinition
    */
   BeanDefinition getBeanDefinition(String beanId);

   /**
    * 獲取bean的實例
    * @param beanId beanId
    * @return bean示例
    */
   Object getBean(String beanId);

}

`DefaultBeanFactory`實現了`BeanFactory`接口

package com.timwang.spring.small;

import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.util.ClassUtils;

import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.dom4j.io.SAXReader;

/**

* BeanFactory的默認實現類
*
* @author wangjun
* @date 2020-06-29
*/

public class DefaultBeanFactory implements BeanFactory {

private static final String ID_ATTRIBUTE = "id";
   private static final String CLASS_ATTRIBUTE = "class";
   /**
    * 存放BeanDefinition
    */
   private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

   public DefaultBeanFactory(String configFile) {
       loadBeanDefinition(configFile);
   }

   @Override
   public BeanDefinition getBeanDefinition(String beanId) {
       return beanDefinitionMap.get(beanId);
   }

   @Override
   public Object getBean(String beanId) {
       BeanDefinition bd = this.getBeanDefinition(beanId);
       if (bd == null) {
           throw new BeanCreationException("BeanDefinition does not exist");
       }
       ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
       String beanClassName =  bd.getBeanClassName();
       try {
           // 使用反射建立bean的實例,須要對象存在默認的無參構造方法
           Class<?> aClass = classLoader.loadClass(beanClassName);
           return aClass.newInstance();
       } catch (Exception e) {
           throw new BeanCreationException("Bean Definition does not exist");
       }
   }

   /**
    * 具體解析bean.xml的方法 使用dom4j
    * @param configFile configFile
    */
   private void loadBeanDefinition(String configFile) {
       ClassLoader cl = ClassUtils.getDefaultClassLoader();
       try (InputStream is = cl.getResourceAsStream(configFile)) {
           SAXReader reader = new SAXReader();
           Document doc = reader.read(is);

           Element root = doc.getRootElement();
           Iterator elementIterator = root.elementIterator();
           while (elementIterator.hasNext()) {
               Element ele = (Element) elementIterator.next();
               String id = ele.attributeValue(ID_ATTRIBUTE);
               String beanClassName = ele.attributeValue(CLASS_ATTRIBUTE);
               BeanDefinition bd = new GenericBeanDefinition(id, beanClassName);
               this.beanDefinitionMap.put(id, bd);
           }
       } catch (Exception e) {
           throw new BeanDefinitionStoreException("IOException parsing XML document", e);
       }
   }

}

4. BeanFactoryTest

package com.timwang.spring.small;

/**

* @author wangjun
* @date 2020-06-29
*/

public class BeanFactoryTest {

public static void main(String[] args) {
       BeanFactoryTest beanFactoryTest = new BeanFactoryTest();
       beanFactoryTest.testGetBean();
   }

   public void testGetBean() {
       BeanFactory beanFactory = new DefaultBeanFactory("bean-v1.xml");
       BeanDefinition bd = beanFactory.getBeanDefinition("user");
       String beanClassName = bd.getBeanClassName();
       System.out.println(beanClassName);
   }

}

相關文章
相關標籤/搜索