@Bean和@Scope
文章内容来自于:
,作者:飞羽127
,作者:罗罗诺亚-小鱼
文章主要用于自己学习SpringBoot,方便以后的查询
@Bean
是一个方法级别上的注解,主要用在@Configuration
和@Compoment
注解的类里
定义Bean
下面是@Configuration
里的一个例子
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
这个配置等同于XML中的配置
<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
Bean的依赖
@Bean
也可以依赖其他任意数量的bean,如果TransferService 依赖 AccountRepository,我们可以通过方法参数实现这个依赖
@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
接收生命周期的回调
任何使用@Bean
定义的bean,也可以执行生命周期的回调函数,类似@PostConstruct
和@PreDestroy
的方法
public class Foo {
public void init() {
// initialization logic
}
}
public class Bar {
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Foo foo() {
return new Foo();
}
@Bean(destroyMethod = "cleanup")
public Bar bar() {
return new Bar();
}
}
默认使用javaConfig
配置的bean
,如果存在close
或者shutdown
方法,则在bean
销毁时会自动执行该方法,如果你不想执行该方法,则添加@Bean(destroyMethod="")
来防止出发销毁方法
自定义Bean的命名
默认情况下bean的名称和方法名称相同,你也可以使用name属性来指定
@Configuration
public class AppConfig {
@Bean(name = "myFoo")
public Foo foo() {
return new Foo();
}
}
Bean的别名
bean的命名支持别名,使用方法如下
@Configuration
public class AppConfig {
@Bean(name = { "dataSource", "subsystemA-dataSource", "subsystemB-dataSource" })
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}
Bean的描述
有时候提供bean的详细信息也是很有用的,bean的描述可以使用 @Description来提供
@Configuration
public class AppConfig {
@Bean
@Description("Provides a basic example of a bean")
public Foo foo() {
return new Foo();
}
}
指定Bean的Scope
你能够使用@Scope
注解来指定使用@Bean
定义的bean
@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
public Encryptor encryptor() {
// ...
}
}
相当于在xml中,配置如下
<!-- 具体的作用域需要在 scope 属性中定义 -->
<bean id="XXX" class="com.XXX.XXXXX" scope="XXXX" />
scope
也称作用域,在 Spring IoC 容器是指其创建的 Bean 对象相对于其他 Bean 对象的请求可见范围。在 Spring IoC 容器中具有以下几种作用域:基本作用域(singleton、prototype)
,Web 作用域(reqeust、session、globalsession)
,自定义作用域
。
- singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
- prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
- request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
- session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
- globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。
如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。
基于注解开发时,@scope完成bean的作用域配置默认是单例模式(singleton)如果需要设置的话可以修改对应值与以上提到的一致例如:@scope(“prototype”)