spring创建模式singleton prototype 方法注入
(2010-10-19 17:38:57)
标签:
it |
分类: java学习 |
我们知道,建造模式中有单例模式(singleton),和原始模型模式(prototype),这两种模式在Spring中应用十分广泛。在默认的情况下,Spring中创建的bean都是单例模式的(注意Spring的单例模式与GoF提到的单例模式略微有些不同,详情参考Spring的官方文档)。一般情况下,有状态的bean需要使用prototype模式,而对于无状态的bean一般采用singleton模式(一般的dao都是无状态的)。下面举个例子说明singleton bean和prototype bean之间的区别,以及Spring中如何实现prototype的创建的(使用方法注入);
先创建两个类:
package com.guan.thirdPart.builder;
import org.springframework.stereotype.Component;
@Component("prototypeClass")
public class PrototypeClass {
}
package com.guan.thirdPart.builder;
import org.springframework.stereotype.Component;
@Component("singletonClass")
public class SingletonClass {
}
这两个类看起来内容相同,都有一个用来保存状态的属性content。一个(singletonClass)我们用来做常规的bean(singleton),一个(prototypeClass)用来做非常规的prototype bean。
下面这个类将会测试出两个类的不同:
package com.guan.thirdPart.builder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("singletonUsePrototype")
public abstract class SingletonPrototypeTest {
}
在上面的测试类中,test函数里两种方式输出并没什么不同,关键点是,singleton是通过属性注入的(当然也可以通过构造函数注入),而prototype这是通过方法注入的(定义了一个抽象的createPrototypeClass方法,通过调用该方法获取prototype对象);
最后给出Spring的配置类,一般情况下,您可能会选择使用xml的方式进行配置,我个人更喜欢Spring新提供的annotation的形式,因为这更接近java。
package com.guan.thirdPart.builder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BuilderApp {
}
看到了这个类中,singleton仅需要创建函数即可,而prototype略显麻烦一些,首先要将prototype的创建函数标记成scope为prototype,然后要在使用prototype的类中给出具体方法的实现,这里通过直接重写创建一个无名子类的无名子对象,直接返回。这里注意的是使用prototype的类必然是抽象类,而在配置文件中必然要将提供其子类。
最后给出整个程序的测试部分:
package com.guan.thirdPart.builder;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicat
public class SingletonAndPrototypeTes
}
输出结果:
singleton prototype use singleton is null
now singleton prototype use singleton is goodgamer
singleton
now singleton
singleton prototype use singleton is goodgamer
now singleton prototype use singleton is gg
singleton
now singleton
singleton prototype use singleton is gg
now singleton prototype use singleton is pl
singleton
now singleton
从结果中很容易看出,每次调用一次test方法,prototype都会提供一个新的对象,并不保存原有的实例,而singleton不同,多次调用test实际上使用的是同一个singleton对象,而且保存了对象的状态信息。
对应这种对象生命期不同的情况(包括,上面提到的,一个singleton使用一个prototype(实际上,SingletonPrototypeTest也是singleton的),或者Web应用中的一个session使用了一个required或者其他的生命期不同的情况(注意这里是指,使用者的生命期大于被使用者)),如果是web模式下需要使用代理模式<aop:scoped-proxy/>,这样使用者持有一个被使用者的代理,当被使用者更换时,代理将会更换相应的引用。