Spring容器中Bean的实例化

2 篇文章 0 订阅
1 篇文章 0 订阅

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值