Spring容器中Bean的实例化

来源:互联网 发布:淘宝怎么搜苍蝇水 编辑:程序博客网 时间:2024/05/16 11:29

Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。这也就使得我们在项目中不分逻辑、业务层次管理Bean都变得非常简单、方便、适用,那么Spring容器是怎么去实例化他所管理的Bean的呢:

说明:本文以JavaWeb环境为例,所用的Spring上下文均为ClassPathXmlApplicationContext

自定义普通Bean

一:作用域为默认(单例)的Bean

1.在Spring容器中声明对NormalService的支持,代码如下:

<!-- 自定义Bean --><bean id="normalService" class="com.zzy.core.service.NormalService" />

2.NormalService代码如下:

public class NormalService {    public NormalService() {        System.out.println(getClass().getName()                + ".NormalService() is running!");    }}

3.测试代码及结果如下

public class NormalTest {    public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext(                "applicationContext.xml");    }}/**  *  控制台输出:com.zzy.core.service.NormalService.NormalService() is running! *  从上述结果可以看出,对于普通的Bean,Spring容器在完成自身自动过程的时候就会对其所管理的Bean进行初始化(调用默认无参构造器实现) */

4.Spring配置文件中bean的配置加上延迟加载配置,代码如下:

<bean id="normalService" class="com.zzy.core.service.NormalService" lazy-init="true" />

再执行上述测试方法,发现控制台无输出,说明在初始化整个Spring容器的时候指定了延迟加载的Bean并不会被初始化,而是在通过上下文获取该Bean的时候被初始化。

public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext(                "applicationContext.xml");        NormalService service = (NormalService) context.getBean(                "normalService", NormalService.class);    /**     * 结果:     *     控制台打印com.zzy.core.service.NormalService.NormalService() is running!     */}

小结:如果一个Spring中的Bean定义成了延迟加载,则在初始化Spring容器的时候并不会初始化改Bean,而是在从容器中获取该Bean的时候才被实例化

二:作用域为原型(多实例)的Bean

1.在Spring配置文件中指定Bean的作用域为原型,即多实例:

<bean id="normalService" class="com.zzy.core.service.NormalService" scope="prototype" />

2.执行测试代码①

public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext(                "applicationContext.xml");}/** *结果: *    执行上述测试代码后控制台无任何输出,同样说明当bean为多实例的时候,初始化Spring容器并不会实例化该Bean */

3.执行测试代码②

public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext(                "applicationContext.xml");        NormalService service1 = (NormalService) context.getBean(                "normalService", NormalService.class);        NormalService service2 = (NormalService) context.getBean(                "normalService", NormalService.class);}/** * 结果: * com.zzy.core.service.NormalService.NormalService() is running! * com.zzy.core.service.NormalService.NormalService() is running! *  */

小结:当一个Bean被定义为原型(scope=”prototype”)的时候,Spring容器在加载的时候并不会去实例化该Bean,而是当你从容器中获取的时候才会实例化,且每获取一次就会实例化一个

结论:

  • 如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取
  • 如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
  • 如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
0 0
原创粉丝点击