Spring中Singleton作用域和Prototype作用域

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq78442761/article/details/89132545

目录

 

 

基本概念

演示


 

基本概念

singleton作用域就是单例模式;用spring容器实现单例模式

而prototype作用域可以理解为多例模式!

Singleton作用域例子:

左侧的ref就是右侧bean的id,这里就是把右边的bean通过spring注入到左侧的bean中;

而Singleton是如下的情况:

而Prototype是这样的

 

演示

如下的文件结构:

Bean1.java

package singleandprodemo.demo;

public class Bean1 {

    private Bean2 bean2;

    public Bean2 getBean2() {
        return bean2;
    }

    public void setBean2(Bean2 bean2) {
        this.bean2 = bean2;
    }

    @Override
    public String toString() {
        return "Bean1{" +
                "bean2=" + bean2 +
                '}';
    }
}

Bean2.java

package singleandprodemo.demo;

public class Bean2 {
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <bean class="singleandprodemo.demo.Bean2" id="bean2" scope="singleton"/>
    <bean class="singleandprodemo.demo.Bean1" id="bean1">
        <property name="bean2" ref="bean2"/>
    </bean>
</beans>

这里要注意bean1没有填写scope,这里没填的默认是scope为singleton

这里编写如下的运行代码:

    public void contextLoads() {

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        Bean2 bean2_1 = context.getBean("bean2", Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_2 = context.getBean("bean2", Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
        Bean1 bean1 = context.getBean("bean1", Bean1.class);
        System.out.println("bean1 = " + bean1);
    }

运行截图如下:

从这里可以知道,单例模式在一个spring上下文环境中,被单例化;

修改如下运行代码:

    public void contextLoads() {

        ApplicationContext context1 = new ClassPathXmlApplicationContext("spring.xml");

        Bean2 bean2_1 = context1.getBean("bean2", Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_2 = context1.getBean("bean2", Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
        Bean1 bean1 = context1.getBean("bean1", Bean1.class);
        System.out.println("bean1 = " + bean1);
        
        System.out.println("---------------华丽的分割线---------------");
        
        ApplicationContext context2 = new ClassPathXmlApplicationContext("spring.xml");
        Bean2 bean2_3 = context2.getBean("bean2", Bean2.class);
        System.out.println("bean2_1 = " + bean2_3);
        Bean2 bean2_4 = context2.getBean("bean2", Bean2.class);
        System.out.println("bean2_2 = " + bean2_4);
        Bean1 bean2 = context2.getBean("bean1", Bean1.class);
        System.out.println("bean1 = " + bean2);
    }

运行截图如下:

可见不同的spring上下文环境中实例的Bean是不一样的;

修改spring.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <bean class="singleandprodemo.demo.Bean2" id="bean2" scope="singleton"/>
    <bean class="singleandprodemo.demo.Bean1" id="bean1" scope="prototype">
        <property name="bean2" ref="bean2"/>
    </bean>
</beans>

运行代码如下:

    public void contextLoads() {

        ApplicationContext context1 = new ClassPathXmlApplicationContext("spring.xml");

        Bean2 bean2_1 = context1.getBean("bean2", Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_2 = context1.getBean("bean2", Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
        Bean1 bean1 = context1.getBean("bean1", Bean1.class);
        Bean1 bean11 = context1.getBean("bean1", Bean1.class);
        System.out.println("bean1 = " + bean1);
        System.out.println("bean11 = " + bean11);
        System.out.println(bean1 == bean11);

    }

运行截图如下:

从这里可以知道,但bean1为prototye的时候,实例化的bean1是不同的,(因为上面的false)

下面给出一张表:

这里如果有这样的一个应用场景:

Bean1是singleton,Bean2是prototype,Bean1依赖Bean2,希望每次调用Bean1的某个方法时,该方法拿到的Bean2都是一个新的实例;

这里使用到了方法注入!!!!!!!!!!!!!!

修改Bean1.java

package singleandprodemo.demo;

public abstract class Bean1 {

    protected abstract Bean2 createBean2();

    public void printBean2(){
        System.out.println("bean2 = " + createBean2());
    }
}

spring.xml
 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <bean class="singleandprodemo.demo.Bean2" id="bean2" scope="prototype"/>
    <bean class="singleandprodemo.demo.Bean1" id="bean1" scope="prototype">
        <!-- <property name="bean2" ref="bean2"/> -->
        <lookup-method name="createBean2" bean="bean2"></lookup-method>
    </bean>
</beans>

测试代码如下:

    public void contextLoads() {

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Bean1 bean1 = context.getBean("bean1", Bean1.class);
        bean1.printBean2();
        bean1.printBean2();
        bean1.printBean2();
        bean1.printBean2();
    }

运行截图如下:

猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/89132545
今日推荐