SpringFramework:以编程方式设置bean名称

min*_*pro 5 java spring

对于基于springframwork的应用程序,使用xml声明bean时,可以通过传递唯一值甚至参数来配置bean id,然后在运行时解析该值。

现在我希望将所有xml配置替换为java注释。

假设我想创建两个具有不同 id 的数据库 bean。

bean.xml
<bean id="A.database" class="org.apache.commons.dbcp.BasicDataSource">
    <!-- collaborators and configuration for this bean go here -->
</bean>   

<bean id="B.database" class="org.apache.commons.dbcp.BasicDataSource">
    <!-- collaborators and configuration for this bean go here -->
</bean> 
Run Code Online (Sandbox Code Playgroud)

然后我将上面的代码优化为一个具有两个应用程序的两个属性文件的bean

bean.xml
<bean id="${appName.database}"   class="org.apache.commons.dbcp.BasicDataSource">
    <!-- collaborators and configuration for this bean go here -->
</bean> 

applicationA.properties    
appName.database=A.database

applicationB.properties
appName.database=B.database
Run Code Online (Sandbox Code Playgroud)

整个应用程序由“框架”模块组成,该模块提供每个应用程序通用的bean,如数据库bean、jdbcTemplate bean,以及“应用程序”模块,该模块为占位符提供属性值并使用唯一id初始化bean。所以即使我同时启动多个应用程序,它们也会从上下文中找到相应的bean。

一般来说,我希望做到

@Bean(name = "${beanName}")
public ABean getBean() {}
Run Code Online (Sandbox Code Playgroud)

并在应用程序级别解析 ${beanName}。

min*_*pro 4

通过阅读SpringFramwork文档,我找到了答案:BeanNameGenerator

名称生成器.class

public class NameGenerator implements BeanNameGenerator{

@Override
public String generateBeanName(BeanDefinition definition,
        BeanDefinitionRegistry registry) {
    if(definition.getBeanClassName().contains("Toto")) {
        return "toto";
    }
    return return definition.getBeanClassName();
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序配置类

@Configuration
@ComponentScan(basePackages = {"com.example.domain"}, nameGenerator = NameGenerator.class)
public class Config {
}
Run Code Online (Sandbox Code Playgroud)

带有@Component的域类

@Component
public class Toto {
    private int id;
}
Run Code Online (Sandbox Code Playgroud)

BootApplication 的域 bean 名称为:toto

@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
    ConfigurableApplicationContext ctx = SpringApplication.run(
            DemoApplication.class, args);
    for (String name : ctx.getBeanNamesForType(Toto.class)) {
        System.out.println(name);
    }
}
}
Run Code Online (Sandbox Code Playgroud)