spring scope中prototype和singleton的区别

1、singleton作用域 
  当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例,这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。 
  
2、prototype 
  prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用。)

现在直接来看代码:

bean的配置:

配置为prototype类型:

<bean id = "personService" scope = "prototype" class = "com.st.beanlife.PersonService">
    <!-- 这里是注入属性,前提就是有setName才能成功 -->
        <property name="name">
            <value>
                小张
            </value>
        </property>
    </bean>
    
    <bean id = "personService2" scope = "prototype" class = "com.st.beanlife.PersonService">
    <!-- 这里是注入属性,前提就是有setName才能成功 -->
        <property name="name">
            <value>
                小红
            </value>
        </property>
    </bean>

配置为singleton类型:

<bean id = "personService" scope = "singleton" class = "com.st.beanlife.PersonService">
    <!-- 这里是注入属性,前提就是有setName才能成功 -->
        <property name="name">
            <value>
                小张
            </value>
        </property>
    </bean>
    
    <bean id = "personService2" scope = "singleton" class = "com.st.beanlife.PersonService">
    <!-- 这里是注入属性,前提就是有setName才能成功 -->
        <property name="name">
            <value>
                小红
            </value>
        </property>
    </bean>

主函数:  

public class App1 {

    public static void main(String[] args) {
        
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/st/beanlife/beans.xml");
        PersonService ps = (PersonService)ac.getBean("personService");
        ps.sayHi();
        
        PersonService ps2 = (PersonService)ac.getBean("personService");
        PersonService ps3 = (PersonService)ac.getBean("personService");
        PersonService ps4 = (PersonService)ac.getBean("personService");

    }

}

PersonService类代码:

public class PersonService implements BeanNameAware,BeanFactoryAware,ApplicationContextAware {
    
    private String name;

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        System.out.println("------------setName(String name)函数-------------");
        this.name = name;
    }
    public void sayHi() {
        
        System.out.println("hi" + name);
    }
    
    
    //构造函数
    public PersonService() {
        //实例化时加载
        System.out.println("-----------------PersonService 构造函数被调用-------------------");
    }
    //该方法可以给arg0表示正在被实例化的bean  id
    public void setBeanName(String arg0) {
        
        System.out.println("-----------------setBeanName被调用值" + arg0);
    }
    //该方法可以给你传递beanFactory对象
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        
        System.out.println("-----------------setBeanFactory被调用值" + arg0);
    }
    //该方法传递ApplicationContext
    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        
        System.out.println("------------------setApplicationContext被调用值" + arg0);
    }
    
    
}

扫描二维码关注公众号,回复: 4757125 查看本文章

输出结果:

配置为prototype时候:

-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:35:39 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:35:40 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:35:40 CST 2018
hi
                小张
            
-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:35:39 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:35:40 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:35:40 CST 2018
-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:35:39 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:35:40 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:35:40 CST 2018
-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:35:39 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:35:40 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:35:40 CST 2018

---------------------------------------以上可以看出加载了几次类----------------------------------------

接下来是配置的singleton:

-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:44:31 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:44:32 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:44:32 CST 2018
-----------------PersonService 构造函数被调用-------------------
------------setName(String name)函数-------------
-----------------setBeanName被调用值personService2
-----------------setBeanFactory被调用值org.springframework.beans.factory.support.DefaultListableBeanFactory@14a66e3f: defining beans [personService,personService2,mybeanPostProfessor]; root of factory hierarchy
------------------setApplicationContext被调用值org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@46a19cc5]; startup date [Wed Dec 12 11:44:31 CST 2018]; root of context hierarchy
postProcessBeforeInitialization 函数被调用
class com.st.beanlife.PersonService创建结束的时间是Wed Dec 12 11:44:32 CST 2018
postProcessAfterInitialization函数被调用
class com.st.beanlife.PersonService被创建的时间是Wed Dec 12 11:44:32 CST 2018
hi
                小张
---------------------------------------------以上可以看出一个类只加载了一次---------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/manchengpiaoxue/article/details/84969874
今日推荐