首页 > 编程语言 > 详细

SpringBean的几个问题以及原理

时间:2020-07-26 23:46:10      阅读:152      评论:0      收藏:0      [点我收藏+]

一、几个问题

  1. Spring中的bean是如何生成?
  2. Spring提供了哪些扩展点可以整合第三方框架
  3. Spring如何整合Mybatis的

二、什么是Spring

Spring管理bean(Java中的对象),初始化的操作,

三、Spring IoC容器

  1. 资源组件:

    Resource,对资源文件的描述,不同资源文件如xml、properties文件等,格式不同,最终都将被ResourceLoader加载获得相应的Resource对象;个人理解是。主配置文件.主配置作为所有配置的入口

  2. 资源加载组件:

    ResourceLoader:加载xml、properties等各类格式文件,解析文件,并生成Resource对象。加载哪些解析过的配置资源

  3. Bean容器组件:

    BeanFactory体系:IoC容器的核心,其他组件都是为它工作的(但不是仅仅为其服务).核心

  4. Bean注册组件:

    SingletonBeanRegister/AliasRegister:将BeanDefinition对象注册到BeanFactory(BeanDefinition Map)中去。注册对象所使用的容器

  5. Bean描述组件:

    BeanDefinition体系,Spring内部对Bean描述的基本数据结构。负责描述BeanDefinition资源 将资源形式的bean转化为spring所期望的格式结构

  6. Bean构造组件:

    BeanDefinitionReader体系,读取Resource并将其数据转换成一个个BeanDefinition对象。负责将一个个的资源 解析转化为BeanDefinition 为之后描述bean做准备

技术分享图片

四、BeanFactory

4.1 准备
  • bean-v1.xml配置bean的信息
  • BeanDefinition用于存放bean的定义
  • BeanFactory获取bean的信息,实例化bean`
  • BeanFactoryTest测试BeanFactory是否可用
4.2 代码实现
  1. bean-v1.xml

    <?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. BeanDefinition

    bean-v1.xml中定义了每个bean,但这些信息我们该如何存储呢? spring是通过BeanDefinition接口来描述bean的定义

    package com.timwang.spring.small;
    
    /**
     * @author wangjun
     * @date 2020-06-29
     */
    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.xmlbean的定义,下面我们使用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);
        }
    }
    
    

SpringBean的几个问题以及原理

原文:https://www.cnblogs.com/yurenjun/p/13382769.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!