java bean prototype_Java Spring之Singleton bean与Prototype bean

Spring创建bean的时候默认是Singleton即单例模式,如果想要创建Prototype模式的需要在bean中设置scope

bean中的singleton模式

Spring在默认的情况下会将容器中的bean以单例模式初始化,这是什么意思呢?通过代码我们可以详细了解到

现在有这样三个类 Person PersonTwo Axe 具体内容如下

Person:

public class Person {

private Axe axe;

public Person(){

System.out.print("初始化了person");

}

public void setAxe(Axe axe){

this.axe = axe;

}

public void useAxe(){

axe.chop();

}

public void setAxeChopString(String chopString){

this.axe.setChopString(chopString);

}

}

PersonTwo:

public class PersonTwo {

private Axe axeTwo;

public PersonTwo(){

System.out.print("初始化了personTwo");

}

public void useAxe(){

this.axeTwo.chop();

}

public void setAxeChopString(String chopString){

this.axeTwo.setChopString(chopString);

}

public void setAxeTwo(Axe axeTwo) {

this.axeTwo = axeTwo;

}

// public Axe getAxeTwo() {

// return axeTwo;

// }

}

Axe:

public class Axe implements AxeInterface{

private String chopString;

public void setChopString(String chopString){

this.chopString = chopString;

}

public void chop(){

System.out.print("\n"+this.chopString);

}

}

bean的设置如下

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

class="Person">

ref="axe"/>

ref="axe"/>

在Person类中我们实现了默认构造方法,方法中打印了一些信息,我们可以先通过初始化两个Person类来看看打印信息打印了几次

public static void main(String[] args){

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");

if (ctx.containsBean("person")){

Person a = (Person) ctx.getBean("person",Person.class);

Person b = (Person) ctx.getBean("person",Person.class);

}

}

运行之后打印信息如下:

初始化了person

Person构造方法只走了一次,说明Person只被初始化了一次,不出意外的a与b指引的是相同的对象。实际上这一次初始化在ApplicationContext创建的时候就进行了具体见ApplicationContext的介绍可参考ApplicationContext

那么我们再来做个试验,将Axe作为bean的property同时赋值给Person和PersonTwo,然后在将Axe也加入到SpringContainer中

public class Application {

public static void main(String[] args){

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");

if (ctx.containsBean("person")){

Person a = (Person) ctx.getBean("person",Person.class);

PersonTwo b = (PersonTwo) ctx.getBean("personTwo",PersonTwo.class);

a.setAxeChopString("去砍柴");

a.useAxe();

b.useAxe();

}

}

}

打印结果如下

初始化了person初始化了personTwo

去砍柴

去砍柴

Person和PersonTwo的初始化方法都被调用了,a与b调用useAxe方法的时候打印了相同的信息,实际上只有a才调用的setAxeChopString方法,证明了a与b指引的对象中的Axe属性赋值的对象是同一个对象,这样在以后的开发中我们就要注意到这种问题,单例机制固然可以起到重用节约资源的目的但在某些情况下确会导致异常情况就比如上面的代码更改一下我给b也调用setAxeChopString方法

public class Application {

public static void main(String[] args){

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");

if (ctx.containsBean("person")){

Person a = (Person) ctx.getBean("person",Person.class);

PersonTwo b = (PersonTwo) ctx.getBean("personTwo",PersonTwo.class);

a.setAxeChopString("去砍柴");

a.useAxe();

b.setAxeChopString("去劈柴");

b.useAxe();

a.useAxe();

}

}

}

打印结果如下

初始化了person初始化了personTwo

去砍柴

去劈柴

去劈柴

我们明明想让a去砍柴,结果在b的作用下确变成了去劈柴,导致了异常,所以在写代码的时候一定要注意这个问题。

通常情况下我们只需要把bean设置成singleton就可以了,Spring也鼓励这么做,能够重用对象节约更多的资源。但是也要注意对象的引用问题,防止上述异常产生

使用ApplicationContext的时候会将容器中所有的singleton bean初始化,这就意味着在系统初期会产生大量的开销,如果想要避免这种开销可以给beans设置懒汉模式

或者单独设置bean的懒汉模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值