有人可以向我解释一个 spring boot 注入的用例
Someone can explain to me for a use case of springboot injection
我从一位同事的代码中读到这些行:
@Bean(name = "mysql")
@ConfigurationProperties(prefix = "spring.mysql")
@Primary
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public ClassA classA () {
return new ClassA (this.mysqlDataSource());
}
@Bean
public ClassB classB () {
return new ClassB (this.mysqlDataSource());
}
我认为这将为 Bean classA 和 classB 创建 2 个数据源。为了注入数据源,我们需要类似的东西:
@Bean
public ClassA classA (DataSource ds) {
return new ClassA (ds);
}
但是Spring 只创建一个数据源,this.mysqlDataSource() returns 每次都创建相同的数据源。它是怎么发生的?如果我确实需要另一个数据源,我需要即时创建它吗?
方法 this.mysqlDataSource()
returns bean 因为 Spring 为配置 class 创建代理。可以查看详情
默认情况下 Spring 容器使用 scope "singleton" 创建 bean。
所以你在容器中有一个 DataSource 实例,这个实例将被注入到 ClassA 和 ClassB 对象。如果你想要不同的实例,你应该将范围更改为 "prototype".
您可以使用注释 @Scope("prototype")
来完成。
Spring 表示 @Component
和 @Configuration
具有不同的含义。
如果您使用 @Configuration
而不是 @Component
,将使用 CGLIB 代理。
"The @Bean
methods in a regular Spring component are processed differently than their counterparts inside a Spring @Configuration
class. The difference is that @Component
classes are not enhanced with CGLIB
to intercept the invocation of methods and fields. CGLIB proxying is the means by which invoking methods or fields within @Bean
methods in @Configuration
classes creates bean metadata references to collaborating objects; such methods are not invoked with normal Java semantics but rather go through the container in order to provide the usual lifecycle management and proxying of Spring beans even when referring to other beans via programmatic calls to @Bean
methods. In contrast, invoking a method or field in an @Bean
method within a plain @Component
class has standard Java semantics, with no special CGLIB
processing or other constraints applying."
https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/core.html#spring-core
或者,您可以将 @ConfigurationProperties
保留在 class 级别并从 DataSource
中删除 @Bean
,这样 mysqlDataSource()
将被视为常规方法..
我从一位同事的代码中读到这些行:
@Bean(name = "mysql")
@ConfigurationProperties(prefix = "spring.mysql")
@Primary
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public ClassA classA () {
return new ClassA (this.mysqlDataSource());
}
@Bean
public ClassB classB () {
return new ClassB (this.mysqlDataSource());
}
我认为这将为 Bean classA 和 classB 创建 2 个数据源。为了注入数据源,我们需要类似的东西:
@Bean
public ClassA classA (DataSource ds) {
return new ClassA (ds);
}
但是Spring 只创建一个数据源,this.mysqlDataSource() returns 每次都创建相同的数据源。它是怎么发生的?如果我确实需要另一个数据源,我需要即时创建它吗?
方法 this.mysqlDataSource()
returns bean 因为 Spring 为配置 class 创建代理。可以查看详情
默认情况下 Spring 容器使用 scope "singleton" 创建 bean。 所以你在容器中有一个 DataSource 实例,这个实例将被注入到 ClassA 和 ClassB 对象。如果你想要不同的实例,你应该将范围更改为 "prototype".
您可以使用注释 @Scope("prototype")
来完成。
Spring 表示 @Component
和 @Configuration
具有不同的含义。
如果您使用 @Configuration
而不是 @Component
,将使用 CGLIB 代理。
"The @Bean
methods in a regular Spring component are processed differently than their counterparts inside a Spring @Configuration
class. The difference is that @Component
classes are not enhanced with CGLIB
to intercept the invocation of methods and fields. CGLIB proxying is the means by which invoking methods or fields within @Bean
methods in @Configuration
classes creates bean metadata references to collaborating objects; such methods are not invoked with normal Java semantics but rather go through the container in order to provide the usual lifecycle management and proxying of Spring beans even when referring to other beans via programmatic calls to @Bean
methods. In contrast, invoking a method or field in an @Bean
method within a plain @Component
class has standard Java semantics, with no special CGLIB
processing or other constraints applying."
https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/core.html#spring-core
或者,您可以将 @ConfigurationProperties
保留在 class 级别并从 DataSource
中删除 @Bean
,这样 mysqlDataSource()
将被视为常规方法..