博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring点滴九:Spring bean的延迟初始化
阅读量:6247 次
发布时间:2019-06-22

本文共 7221 字,大约阅读时间需要 24 分钟。

Spring bean延迟初始化:

官网API:

By default, ApplicationContext implementations eagerly create and configure all beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

译文:默认情况下,Spring 容器在初始化过程中会创建和配置所有单例的bean。这种提前实例化是可取的,因为配置环境错误会被立即发现而不需要过多的时间。如果不采取这种行为,可以将单例的bean标记为延迟初始化。一个延迟初始化的bean告诉Spring IoC容器去创建这个bean实例化对象当它第一次被调用时而不是在容器启动时立即创建。

在Spring Bean声明周期这篇文档中

将beanLifecycle定义添加lazy-init="true"属性

测试:

package com.test.spring;import org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class T {    ApplicationContext applicationcontext=null;    @Before    public void before() {        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");    }    @Test    public void  test() {
        String [] beans=applicationcontext.getBeanDefinitionNames();         for(String beanName:beans){
            System.out.println(beanName);         } //BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class); }}

 

测试结果:

》》》Spring ApplicationContext容器开始初始化了......

2017-03-19 16:43:58  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 16:43:58 CST 2017]; root of context hierarchy
2017-03-19 16:43:59  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
》》》Spring ApplicationContext容器初始化完毕了......
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0
beanLifecycle
postProcessor

***********

发现Spring IoC容器中虽然有beanLifecycle ID,但是容器并没有实例化它,因为beanLifecycle的创建信息没有被执行

**********

将测试中BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class)这段代码解除注释,beanLifecycle被第一次请求,容器会立即创建它。

------------------------------------------------------------------------------------------------------------------------------------------------

测试结果:

》》》Spring ApplicationContext容器开始初始化了......

2017-03-19 16:49:21  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@406c9125: startup date [Sun Mar 19 16:49:21 CST 2017]; root of context hierarchy
2017-03-19 16:49:21  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
》》》Spring ApplicationContext容器初始化完毕了......
narCodeService
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0
beanLifecycle
postProcessor
》》》调用无参构造方法了
》》》调用BeanLifecycle对象null属性set方法,设值为:张三
》》》调用BeanLifecycle对象null属性set方法,设值为:男
》》》调用BeanNameAware接口setBenaName方法: beanLifecycle
》》》调用BeanFactoryAware接口setBeanFactory方法:org.springframework.beans.factory.support.DefaultListableBeanFactory@5ccc995c: defining beans [narCodeService,org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0,beanLifecycle,postProcessor]; root of factory hierarchy
》》》调用ApplicationContextAware接口setApplicationContext方法:org.springframework.context.support.ClassPathXmlApplicationContext@406c9125: startup date [Sun Mar 19 16:49:21 CST 2017]; root of context hierarchy
后置处理器处理bean=【beanLifecycle】开始
》》》注解初始化方法被调用
》》》BeanLifecycle调用了InitailizingBean的afterPorpertiesSet方法了.....
》》》init方法被调用
后置处理器处理bean=【beanLifecycle】完毕!

但是有一点需要注意就是:当一个非延迟初始化单例bean需要依赖注入一个延迟初始化bean,Spring 容器会立即创建这个延迟初始化的bean。因为它要满足单例的相关性

官网API:

However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean elsewhere that is not lazy-initialized.

示例:

在Spring配置文件中添加如下bean定义(基于Spring Bean声明周期这篇文档中):

新建Test类:

package com.test.spring;public class Test {    private  BeanLifecycle beanLifecycle;    public BeanLifecycle getBeanLifecycle() {        return beanLifecycle;    }    public void setBeanLifecycle(BeanLifecycle beanLifecycle) {        this.beanLifecycle = beanLifecycle;    }    }

测试:

package com.test.spring;import org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class T {    ApplicationContext applicationcontext=null;    @Before    public void before() {        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");    }    @Test    public void  test() {        //BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class);        String [] beans=applicationcontext.getBeanDefinitionNames();        for(String beanName:beans){            System.out.println(beanName);        }       //applicationcontext.getBean(BeanLifecycle.class);    }}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......

2017-03-19 17:06:19  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@406c9125: startup date [Sun Mar 19 17:06:19 CST 2017]; root of context hierarchy
2017-03-19 17:06:19  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
》》》调用无参构造方法了
》》》调用BeanLifecycle对象null属性set方法,设值为:张三
》》》调用BeanLifecycle对象null属性set方法,设值为:男
》》》调用BeanNameAware接口setBenaName方法: beanLifecycle
》》》调用BeanFactoryAware接口setBeanFactory方法:org.springframework.beans.factory.support.DefaultListableBeanFactory@76e9e1a0: defining beans [narCodeService,org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0,beanLifecycle,postProcessor,test]; root of factory hierarchy
》》》调用ApplicationContextAware接口setApplicationContext方法:org.springframework.context.support.ClassPathXmlApplicationContext@406c9125: startup date [Sun Mar 19 17:06:19 CST 2017]; root of context hierarchy
后置处理器处理bean=【beanLifecycle】开始
》》》注解初始化方法被调用
》》》BeanLifecycle调用了InitailizingBean的afterPorpertiesSet方法了.....
》》》init方法被调用
后置处理器处理bean=【beanLifecycle】完毕!
后置处理器处理bean=【test】开始
后置处理器处理bean=【test】完毕!
》》》Spring ApplicationContext容器初始化完毕了......
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0
beanLifecycle
postProcessor
test

从输出信息看到:beanLifecycle被容器创建了。

 

转载于:https://www.cnblogs.com/sishang/p/6580945.html

你可能感兴趣的文章
如果,你的DNS提供商遭遇DDoS攻击该怎么办?
查看>>
Ubuntu环境下检查CPU的温度
查看>>
25G交换机:未来数据中心的“潜力股”
查看>>
OpenWrt开发者沙龙:立方体CEO何铮演讲
查看>>
如何伪装成一个年薪 20 万刀以上的码农?
查看>>
智能家居无线通信技术,Zigbee一马当先
查看>>
雷军再提智能家居,话中有话?
查看>>
《深入理解C++11:C++ 11新特性解析与应用》——2.8 非静态成员的sizeof
查看>>
心脏起搏器中存在巨大安全隐患 或威胁患者生命
查看>>
20 万中国产 WiFi 摄像头曝漏洞,后门大开任由黑客进入
查看>>
《HTML 5+CSS 3入门经典》——1.2 HTML 5 的优势
查看>>
中国通信和IT设备产业:在变革中寻求新突破
查看>>
独家丨2017全国深度学习技术应用大会回顾:传统的AI研究方法,在DL时代该如何变革?...
查看>>
《高性能Linux服务器构建实战》——2.3节配置Varnish
查看>>
创业大学|什么样的BP能让投资人一见钟情
查看>>
入侵CIA和FBI的黑客:可能是一个15岁少年
查看>>
光伏竞价上网 项目盈利将逐步回归均值
查看>>
x86服务器的王者之战 —— 戴尔PowerEdge服务器在全球及亚太市场排名第一
查看>>
《高性能Linux服务器构建实战》——1.6节Nginx性能优化技巧
查看>>
杨永智:我有一些区块链应用的经验可以传授 | 硬创公开课
查看>>