Spring中singleton和prototype的区别?
下面是@Configuration里的一个例子
@Configuration
public class AppConfig {
@Bean//默认方法名为BeanID
public UserDAO userDAO() {
return new UserDAOImpl();
}
@Bean("userService")
// @Scope("singleton") //默认情况下,scope="singleton"--表示单利
@Scope("prototype") //多例模式
public UserService initService() {
UserService userService = new UserServiceImpl();
userService.setUserDAO(userDAO());
return userService;
}
}
这个配置就等同于之前在xml里的配置
<!-- <context:component-scan base-package="top.xiongmingcai.spring"/>-->
<bean class="top.xiongmingcai.spring.injection.dao.UserDAOImpl" id="userDAO"/>
<bean class="top.xiongmingcai.spring.injection.service.UserServiceImpl" id="singleton" scope="prototype">
<property name="userDAO" ref="userDAO"/>
</bean>
@Scope("Singleton") 或者 @Scope,因为默认情况下就是 单例的;
区别
public class InjectionApplication {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:injection.xml");
//UserService userService = (UserService) ctx.getBean("userService");
//UserService userService2 = (UserService) ctx.getBean("userService");
// System.out.println(userService == userService2);
}
}

如图所示:单例模式在IOC初始化时就会实例化对象、prototype则在
访问 ctx.getBean("userService") 创建对象
总结:
- singleton 只有一个实例,也即是单例模式。
- prototype 访问一次创建一个实例,相当于new。
应用场合:
- 1.需要回收重要资源(数据库连接等)的事宜配置为singleton,如果配置为prototype需要应用确保资源正常回收。
- 2.有状态的Bean配置成singleton会引发未知问题,可以考虑配置为prototype。
扩展
在Spring2.0中除了以前的Singleton和Prototype外又加入了三个新的web作用域,分别为 request、session和 global session。
- request,如果在同一个“request”请求内,对象是同一个,不同的请求,IOC容器会创建不同的对象
- session,同一个session内部,多次调用getBean()获取的是同一个对象,不同的session IOC会创建不同的对象
lazy-init -->表示延迟初始化(懒加载)
@Lazy
@Bean("userService")
// @Scope("singleton") //默认情况下,scope="singleton"--表示单利
// @Scope("prototype") //多例模式
public UserService initService() {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO());
return userService;
}
lazy-init 会把对象实例化的过程,放在getBean()方法执行时。
1,设置为“true”--表示只有用到这个javaBean时,才会实例化。
注意:当scope属性为“prototype”多例模式时,lazy-init就会失效
azy-init 有自己的使用场景,因为其作用是,对象在第一次getBean()是被创建,所以可以起到减小服务器压力的作用。
(比如:当前有上千个类,但并不是所有的类都是目前需要的,有些是作为备用选项使用的。此时我们就可以使用lazy-init 来减轻服务器和内存的压力,有利于系统的快速启动)