在默认状况下,Spring应用上下文中全部的bean都是以单例(singleton)的形式建立的,即无论给定的一个bean被注入到其余bean多少次,每次所注入的都是同一个实例。java
Spring定义了多种做用域,能够基于这些做用域建立bean:git
单例是默认的做用域,若是要使用其它的做用域建立bean,须要使用@Scope
注解,该注解能够和@Component
,@Service
,@Bean
等注解一块儿使用。github
为了更好的理解,咱们经过具体的代码示例来理解下Singleton与ProtoType的区别。spring
package chapter03.scope;
import org.springframework.stereotype.Service;
@Service
public class DemoSingletonService {
}
复制代码
由于Spring默认配置的Scope是Singleton,所以以上代码等价于如下代码:微信
package chapter03.scope;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DemoSingletonService {
}
复制代码
上面的代码也能够写成@Scope("singleton")
。测试
若是是自动装配bean,语法为:spa
package chapter03.scope;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoPrototypeService {
}
复制代码
上面的代码也能够写成@Scope("prototype")
。prototype
若是是在Java配置类中声明bean,语法为:code
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public DemoPrototypeService demoPrototypeService() {
return new DemoPrototypeService();
}
复制代码
若是是在xml中声明bean,语法为:cdn
<bean id="demoPrototypeService" class="chapter03.scope.DemoPrototypeService" scope="prototype"/>
复制代码
package chapter03.scope;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("chapter03.scope")
public class ScopeConfig {
}
复制代码
新建一个Main类,在main()方法中,分别从Spring容器中获取2次Bean,而后判断Bean的实例是否相等:
package chapter03.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);
DemoSingletonService s1 = context.getBean(DemoSingletonService.class);
DemoSingletonService s2 = context.getBean(DemoSingletonService.class);
DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class);
DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class);
System.out.println("s1 与 s2 是否相等:" + s1.equals(s2));
System.out.println("p1 与 p2 是否相等:" + p1.equals(p2));
context.close();
}
}
复制代码
运行结果以下:
从运行结果也能够看出,默认状况下即Singleton类型的Bean,无论调用多少次,只会建立一个实例。
Singleton类型的Bean,@Scope注解的值必须是:singleton。
ProtoType类型的Bean,@Scope注解的值必须是:prototype。
即便是大小写不一致也不行,如咱们将DemoPrototypeService类的代码修改成:
package chapter03.scope;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("PROTOTYPE")
public class DemoPrototypeService {
}
复制代码
此时运行代码,就会报错:
源码地址:github.com/zwwhnly/spr…,欢迎下载。
汪云飞《Java EE开发的颠覆者:Spring Boot实战》
最后,欢迎关注个人微信公众号:「申城异乡人」,全部博客会同步更新。