回炉重造Spring 之 Bean
spring

Spring Bean 的定义应该可以理解为由IoC配置、实例化及管理的对象,通过 Bean Definitiion 来进行初始化。

Spring Bean 配置的常见方式

  1. XML 配置
  2. JavaConfig 配置
  3. 注解配置

Spring Bean 的作用域

  1. Singleton - 默认,每个 IoC 容器只有一个实例
  2. Prototype - 每次请求都会产生一个新的实例
  3. Request - 每一次 HTTP 请求都会产生一个新的 Bean 实例,并且该 Bean 仅在当前 HTTP 请求内有效。
  4. Session - 每一个的 Session 都会产生一个新的 Bean 实例,同时该 Bean 仅在当前 HTTP Session 内有效。
  5. Application - 每一个 Web Application 都会产生一个新的 Bean ,同时该 Bean 仅在当前 Web Application 内有效。

当且仅当为 web 的ApplicationContext的时候后三者才有效。

Spring Bean 的生命周期管理

举例通过 Xml配置文件来梳理流程。

ClassPathResource  resource = new ClassPathResource("...");
DefaultListenableFactory factory = new DefaultListenableFactory();
XmlBeanDefinitionReader  reader = new XmlBeanDefinitionReader(dlf);
reader.loadBeanDefinitions(resource);

Resource -> XmlFactory -> XmlBeanDefinitialReader -> XmlBeanDefinitialReader#loadBeanDefinitions 来进行Bean 的初始化。
那么其中的 Bean 是如何进行存放的呢?从最后一个调用函数 loadBeanDefinitions(resource) 分析:

加载关键逻辑代码

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return this.loadBeanDefinitions(new EncodedResource(resource));
    }

    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Loading XML bean definitions from " + encodedResource);
        }

        Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }

        if (!((Set)currentResources).add(encodedResource)) {
            throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        } else {
            int var5;
            try {
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }

                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } catch (IOException var15) {
                throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
            } finally {
                ((Set)currentResources).remove(encodedResource);
                if (((Set)currentResources).isEmpty()) {
                    this.resourcesCurrentlyBeingLoaded.remove();
                }

            }

            return var5;
        }
    }

参考链接列表:

【死磕 Spring】—– IOC 之 加载 Bean
Spring源码阅读——ClassPathXmlApplicationContext(三)

暂无评论