译--Spring中 bean定义profiles的使用 javaConfig 和XML配置

本文内容纲要:

- XML bean 定义 profiles

- 激活profile

- 默认profile

原文地址:http://docs.spring.io/spring/docs/5.0.0.M4/spring-framework-reference/htmlsingle/#beans-property-source-abstraction

bean定义profiles是核心容器内的一种机制,该机制能在不同环境中注册不同的bean。环境的意思是,为不同的用户做不同的事儿,该功能在很多场景中都非常有用,包括:

  • 开发期使用内存数据源,在QA或者产品上则使用来自JNDI的相同的数据源
  • 开发期使用监控组件,当部署以后则关闭监控组件,是应用更高效
  • 为用户各自注册自定义bean实现

考虑一个实际应用中的场景,现在需要一个DataSource。开测试环境中,这样配置:

@Bean

public DataSource dataSource() {

return new EmbeddedDatabaseBuilder()

.setType(EmbeddedDatabaseType.HSQL)

.addScript("my-schema.sql")

.addScript("my-test-data.sql")

.build();

}

现在让我们考虑如何将此应用程序部署到QA或生产环境中,假设应用程序的数据源将注册到生产应用程序服务器的JNDI目录。 我们的dataSource bean现在看起来像这样:

@Bean(destroyMethod="")

public DataSource dataSource() throws Exception {

Context ctx = new InitialContext();

return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");

}

问题是,在当前环境中如何切换这两个配置。随着时间推移,Spring用户设计了很多种方式完成此切换,通常使用系统环境变量和XML<import/>绑定,<import/>元素包含一个${placeholder}符号,使用环境变量来设置${placeholder}符号所代表的值,从而达到切换正确配置文件的目的。bean定义profiles是核心容器功能,提供针对子问题的解决方案。

概括一下上面的场景:环境决定bean定义,最后发现,我们需要在某些上下文环境中使用某些bean,在其他环境中则不用这些bean。你也许会说,你需要在场景A中注册一组bean定义,在场景B中注册另外一组。先看看我们如何修改配置来完成此需求。

@Profile

@Profile注解用于当一个或多个配置文件激活的时候,用来指定组件是否有资格注册。 使用上面的例子,我们可以重写dataSource配置如下:

@Configuration

@Profile("dev")

public class StandaloneDataConfig {

@Bean

public DataSource dataSource() {

return new EmbeddedDatabaseBuilder()

.setType(EmbeddedDatabaseType.HSQL)

.addScript("classpath:com/bank/config/sql/schema.sql")

.addScript("classpath:com/bank/config/sql/test-data.sql")

.build();

}

}

@Configuration

@Profile("production")

public class JndiDataConfig {

@Bean(destroyMethod="")

public DataSource dataSource() throws Exception {

Context ctx = new InitialContext();

return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");

}

}

如前所述,使用@Bean方法,通常会选择使用JNDI查找:使用Spring的JndiTemplate /JndiLocatorDelegatehelper或上面显示的直接JNDIInitialContext用法,但不是JndiObjectFactoryBean 这将使你声明返回类型必须为FactoryBean类型

@Profile可以用作meta-annotation,用于创建自定义组合注解。 下面的例子定义了一个自定义@Production注解,该注解用于替换

@Profile("production"):

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Profile("production")

public @interface Production {

}

@Profile也能注解方法,用于配置一个配置类中的指定bean:

@Configuration

public class AppConfig {

@Bean

@Profile("dev")

public DataSource devDataSource() {

return new EmbeddedDatabaseBuilder()

.setType(EmbeddedDatabaseType.HSQL)

.addScript("classpath:com/bank/config/sql/schema.sql")

.addScript("classpath:com/bank/config/sql/test-data.sql")

.build();

}

@Bean

@Profile("production")

public DataSource productionDataSource() throws Exception {

Context ctx = new InitialContext();

return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");

}

}

如果@Configuration类标有@Profile,类中@Bean@Import注解相关的类都将被忽略,除非该profile被激活。 如果一个@Component@Configuration类被标记为@Profile({“p1”,“p2”}),那么除非profile'p1'和/或’p2’ 已被激活。否则该类将不会注册/处理。 如果给定的配置文件以NOT运算符(!)为前缀,如果配置文件为 not active,则注册的元素将被注册。 例如,给定@Profile({“p1”,“!p2”}),如果配置文件’p1’激活或配置文件’p2’没有激活,则会注册。

XML bean 定义 profiles

XML配置是作为<beans> 的一个属性, 我们上面的示例配置能够用下面的两个XML文件来重写, 如下:

<beans profile="dev"

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:jdbc="http://www.springframework.org/schema/jdbc"

xsi:schemaLocation="...">

<jdbc:embedded-database id="dataSource">

<jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>

<jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>

</jdbc:embedded-database>

</beans>

<beans profile="production"

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:jee="http://www.springframework.org/schema/jee"

xsi:schemaLocation="...">

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>

</beans>

避免上面两个文件分开也是有可能的, 通过在相同的文件中嵌套<beans/> 元素。

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:jdbc="http://www.springframework.org/schema/jdbc"

xmlns:jee="http://www.springframework.org/schema/jee"

xsi:schemaLocation="...">

<!-- other bean definitions -->

<beans profile="dev">

<jdbc:embedded-database id="dataSource">

<jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>

<jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>

</jdbc:embedded-database>

</beans>

<beans profile="production">

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>

</beans>

</beans>

激活profile

既然我们已经更新了配置, 我们仍然需要告知Spring哪一个profile 是激活的。 如果我们现在就启动我们的示例应用, 我们将会看到NoSuchBeanDefinitionException 抛出, 因为容器不能找到名为dataSource 的Spring bean。

可以采用一些方式激活profile, 但是最直接的方式是依靠Environment API用编程方式来配置,通过ApplicationContext 来获取Environment

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

ctx.getEnvironment().setActiveProfiles("dev");

ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);

ctx.refresh();

另外, profiles 可能通过spring.profiles.active 属性来声明式的激活, 此属性可能在系统环境变量, JVM系统属性, web.xml 定义的 servlet上下文参数中被指定, 或着甚至可以作为JNDI的一个元组(entry), 在集成测试中。 在spring-test 模块中可以通过@ActiveProfiles 注解来激活profiles。

注意 profiles 并不是“或着-或着”的命题, 一次性激活多个profiles也是有可能的, 编程式地,简单的向setActiveProfiles() 方法中提供多个profile名称, 它接受String... 参数:

ctx.getEnvironment().setActiveProfiles("profile1", "profile2");

声明式地配置,spring.profiles.active 可以接受以逗号分隔的profile名称列表:

-Dspring.profiles.active="profile1,profile2"

默认profile

默认profile 表示这个profile默认的被启用。如下:

@Configuration

@Profile("default")

public class DefaultDataConfig {

@Bean

public DataSource dataSource() {

return new EmbeddedDatabaseBuilder()

.setType(EmbeddedDatabaseType.HSQL)

.addScript("classpath:com/bank/config/sql/schema.sql")

.build();

}

}

如果没有profile被激活, 那么上面的dataSource 将会被创建; 这可以被看作是为一个或多个beans提供一个默认定义 的一种方式。如果有任一bean被激活, 默认profile将不会生效。

默认profile的名称可以被改变, 在Environment中使用setDefaultProfiles() , 或着声明式的使用spring.profiles.default 属性。

本文内容总结:XML bean 定义 profiles,激活profile,默认profile,

原文链接:https://www.cnblogs.com/cbam/p/11816522.html

以上是 译--Spring中 bean定义profiles的使用 javaConfig 和XML配置 的全部内容, 来源链接: utcz.com/z/362385.html

回到顶部