+-
@Configuration注解详解
首页 专栏 java 文章详情
0
头图

@Configuration注解详解

zensezz 发布于 5 月 14 日

@Configuration注解详解

Configuration代码简介

Configuration注释类表明其主要目的是作为bean定义的源;@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value() default ""; }

一个类声明一个或多个 @Bean方法,并且可以由Spring容器进行处理,以在运行时为这些bean生成bean定义和服务请求,例如:

public class AppConfig { @Bean public MyBean myBean() { // instantiate, configure and return bean ... } }
@Configuration解读

@Configuration 类通使用 AnnotationConfigApplicationContext或具有Web功能的org.springframework.web.context.support.AnnotationConfigWebApplicationContext AnnotationConfigWebApplicationContext进行引导,如下

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); MyBean myBean = ctx.getBean(MyBean.class); // use myBean ...

直接在AnnotationConfigApplicationContext上注册 @Configuration类的替代方法,可以在Spring的XML文件中将 @Configuration类声明为普通<bean>定义:

<beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>}

在上面的示例中,<context:annotation-config/>,启用ConfigurationClassPostProcessor和其他与注解相关的后置处理器,来处理 @Configuration。

@Configuration 用 @Component进行元注释,所以 @Configuration类可以是组件扫描的对象;用Spring XML的 <context:component-scan />,所以也可以像常规 @Component一样利用 @Autowired 或者javax.inject.Inject @Inject。如果存在单个构造函数,则自动装配语义将透明地应用

@Configuration public class AppConfig { private final SomeBean someBean; public AppConfig(SomeBean someBean) { this.someBean = someBean; } // @Bean definition using "SomeBean" }
@Configuration技巧
可以通过将Spring的org.springframework.core.env.Environment注入@Configuration类中需要的外部环境值;例如,使用 @Autowired 注解即可: @Configuration public class AppConfig { @Autowired Environment env; @Bean public MyBean myBean() { MyBean myBean = new MyBean(); myBean.setName(env.getProperty("bean.name")); return myBean; } } Environment解析的属性驻留在一个或多个“属性源”对象, @Configuration 可以使用 org.springframework.core.env.PropertySources @PropertySources注解: @Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Inject Environment env; @Bean public MyBean myBean() { return new MyBean(env.getProperty("bean.name")); } } 可以使用@Value将外部化的值连接到 @Configuration类中 @Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Value("${bean.name}") String beanName; @Bean public MyBean myBean() { return new MyBean(beanName); } }

当使用Spring的 org.springframework.context.support.PropertySourcesPlaceholderConfigurer
PropertySourcesPlaceholderConfigurer, 通常用<context:property-placeholder />的XML开启。

@Configuration 类可以使用@Import注解组成,与 <import>在Spring XML中的工作方式不同。 @Configuration 对象作为容器内的Spring bean管理,所以导入的配置可以按普通的方式注入(例如,通过构造函数注入): @Configuration public class DatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return DataSource } } @Configuration @Import(DatabaseConfig.class) public class AppConfig { private final DatabaseConfig dataConfig; public AppConfig(DatabaseConfig dataConfig) { this.dataConfig = dataConfig; } @Bean public MyBean myBean() { // reference the dataSource() bean method return new MyBean(dataConfig.dataSource()); } }

所以可以通过仅针对Spring上下文注册 AppConfig来引导AppConfig和导入的 DatabaseConfig

new AnnotationConfigApplicationContext(AppConfig.class);

@Configuration 类可以用 @Profile注解进行标记,以指示仅当给定的一个或多个配置文件为 active时才应对其进行处理

@Profile("development") @Configuration public class EmbeddedDatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return embedded DataSource } }

另外,也可以在 @Bean方法级别,例如 声明配置文件条件。对于同一配置类中的替代bean变体:

@Configuration public class ProfileDatabaseConfig { @Bean("dataSource") @Profile("development") public DataSource embeddedDatabase() { ... } @Bean("dataSource") @Profile("production") public DataSource productionDatabase() { ... } }

如上所述,在XML文件中,可以将 @Configuratio}类声明为常规Spring <bean>定义。也可以使用 @ImportResource注解将Spring XML配置文件导入到@Configuration类中。从XML导入的Bean定义可以按通常的方式注入(例如,使用Inject注解)

@Configuration @ImportResource("classpath:/com/acme/database-config.xml") public class AppConfig { @Inject DataSource dataSource; // from XML @Bean public MyBean myBean() { // inject the XML-defined dataSource bean return new MyBean(this.dataSource); } } @Configuration类可以相互嵌套,如下所示: @Configuration public class AppConfig { @Inject DataSource dataSource; @Bean public MyBean myBean() { return new MyBean(dataSource); } @Configuration static class DatabaseConfig { @Bean DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } } }

当这样引导时,仅需要针对应用程序上下文注册AppConfig。由于是嵌套的 @Configuration, DatabaseConfig 将自动注册。 AppConfig.DatabaseConfig之间的关系已经隐式清除时,避免了使用 @Import注释。注意,嵌套的@Configuration类可以与@Profile注解一起使用,以为封闭的 @Configuration提供同一bean的两个选项。默认情况下,@Bean方法将在容器引导时被实例化。为了避免这种情况,可以将 @Configuration与 @Lazy注解结合使用,以指示默认情况下默认初始化了类中声明的所有 @Bean方法。@Lazy 也可以在单独的 @Bean方法上使用。

spring-test模块中的Spring的TestContext框架提供了 @ContextConfiguration注解,从Spring 3.1开始,该注解可以接受 @Configuration的数组类对象: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={AppConfig.class, DatabaseConfig.class}) public class MyTests { @Autowired MyBean myBean; @Autowired DataSource dataSource; @Test public void test() { // assertions against myBean ... } }

使用 @Enable注解启用内置的Spring功能,比如异步方法执行,定时任务执行,注释驱动的事务管理和SpringMVC类的Spring功能都可以启用和通过@Configuration类进行配置使用各自的“ @Enable”注释。
比如

org.springframework.scheduling.annotation.EnableAsync,@EnableAsync
org.springframework.scheduling.annotation.EnableScheduling @EnableScheduling,
org.springframework.transaction.annotation.EnableTransactionManagement @EnableTransactionManagement
org.springframework.context.annotation.EnableAspectJAutoProxy @EnableAspectJAutoProxy,
rg.springframework.web.servlet.config.annotation.EnableWebMvc @EnableWebMvc

@Configuration的约束
Configuration类必须作为类提供(即不作为从工厂方法返回的实例),以允许通过生成的子类增强运行时 配置类必须不是final。 配置类必须是非本地的(即,不能在方法中声明)。 任何嵌套的配置类都必须声明为static。 @Bean 方法不会再创建其他配置类(任何此类实例都将被视为常规Bean,其配置注释不会被检测到)。
java spring
阅读 35 发布于 5 月 14 日
收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
Spring详解
个人简介
关注专栏
avatar
zensezz

个人简介

1 声望
0 粉丝
关注作者
0 条评论
得票数 最新
提交评论
你知道吗?

注册登录
avatar
zensezz

个人简介

1 声望
0 粉丝
关注作者
宣传栏
目录

@Configuration注解详解

Configuration代码简介

Configuration注释类表明其主要目的是作为bean定义的源;@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value() default ""; }

一个类声明一个或多个 @Bean方法,并且可以由Spring容器进行处理,以在运行时为这些bean生成bean定义和服务请求,例如:

public class AppConfig { @Bean public MyBean myBean() { // instantiate, configure and return bean ... } }
@Configuration解读

@Configuration 类通使用 AnnotationConfigApplicationContext或具有Web功能的org.springframework.web.context.support.AnnotationConfigWebApplicationContext AnnotationConfigWebApplicationContext进行引导,如下

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); MyBean myBean = ctx.getBean(MyBean.class); // use myBean ...

直接在AnnotationConfigApplicationContext上注册 @Configuration类的替代方法,可以在Spring的XML文件中将 @Configuration类声明为普通<bean>定义:

<beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>}

在上面的示例中,<context:annotation-config/>,启用ConfigurationClassPostProcessor和其他与注解相关的后置处理器,来处理 @Configuration。

@Configuration 用 @Component进行元注释,所以 @Configuration类可以是组件扫描的对象;用Spring XML的 <context:component-scan />,所以也可以像常规 @Component一样利用 @Autowired 或者javax.inject.Inject @Inject。如果存在单个构造函数,则自动装配语义将透明地应用

@Configuration public class AppConfig { private final SomeBean someBean; public AppConfig(SomeBean someBean) { this.someBean = someBean; } // @Bean definition using "SomeBean" }
@Configuration技巧
可以通过将Spring的org.springframework.core.env.Environment注入@Configuration类中需要的外部环境值;例如,使用 @Autowired 注解即可: @Configuration public class AppConfig { @Autowired Environment env; @Bean public MyBean myBean() { MyBean myBean = new MyBean(); myBean.setName(env.getProperty("bean.name")); return myBean; } } Environment解析的属性驻留在一个或多个“属性源”对象, @Configuration 可以使用 org.springframework.core.env.PropertySources @PropertySources注解: @Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Inject Environment env; @Bean public MyBean myBean() { return new MyBean(env.getProperty("bean.name")); } } 可以使用@Value将外部化的值连接到 @Configuration类中 @Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Value("${bean.name}") String beanName; @Bean public MyBean myBean() { return new MyBean(beanName); } }

当使用Spring的 org.springframework.context.support.PropertySourcesPlaceholderConfigurer
PropertySourcesPlaceholderConfigurer, 通常用<context:property-placeholder />的XML开启。

@Configuration 类可以使用@Import注解组成,与 <import>在Spring XML中的工作方式不同。 @Configuration 对象作为容器内的Spring bean管理,所以导入的配置可以按普通的方式注入(例如,通过构造函数注入): @Configuration public class DatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return DataSource } } @Configuration @Import(DatabaseConfig.class) public class AppConfig { private final DatabaseConfig dataConfig; public AppConfig(DatabaseConfig dataConfig) { this.dataConfig = dataConfig; } @Bean public MyBean myBean() { // reference the dataSource() bean method return new MyBean(dataConfig.dataSource()); } }

所以可以通过仅针对Spring上下文注册 AppConfig来引导AppConfig和导入的 DatabaseConfig

new AnnotationConfigApplicationContext(AppConfig.class);

@Configuration 类可以用 @Profile注解进行标记,以指示仅当给定的一个或多个配置文件为 active时才应对其进行处理

@Profile("development") @Configuration public class EmbeddedDatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return embedded DataSource } }

另外,也可以在 @Bean方法级别,例如 声明配置文件条件。对于同一配置类中的替代bean变体:

@Configuration public class ProfileDatabaseConfig { @Bean("dataSource") @Profile("development") public DataSource embeddedDatabase() { ... } @Bean("dataSource") @Profile("production") public DataSource productionDatabase() { ... } }

如上所述,在XML文件中,可以将 @Configuratio}类声明为常规Spring <bean>定义。也可以使用 @ImportResource注解将Spring XML配置文件导入到@Configuration类中。从XML导入的Bean定义可以按通常的方式注入(例如,使用Inject注解)

@Configuration @ImportResource("classpath:/com/acme/database-config.xml") public class AppConfig { @Inject DataSource dataSource; // from XML @Bean public MyBean myBean() { // inject the XML-defined dataSource bean return new MyBean(this.dataSource); } } @Configuration类可以相互嵌套,如下所示: @Configuration public class AppConfig { @Inject DataSource dataSource; @Bean public MyBean myBean() { return new MyBean(dataSource); } @Configuration static class DatabaseConfig { @Bean DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } } }

当这样引导时,仅需要针对应用程序上下文注册AppConfig。由于是嵌套的 @Configuration, DatabaseConfig 将自动注册。 AppConfig.DatabaseConfig之间的关系已经隐式清除时,避免了使用 @Import注释。注意,嵌套的@Configuration类可以与@Profile注解一起使用,以为封闭的 @Configuration提供同一bean的两个选项。默认情况下,@Bean方法将在容器引导时被实例化。为了避免这种情况,可以将 @Configuration与 @Lazy注解结合使用,以指示默认情况下默认初始化了类中声明的所有 @Bean方法。@Lazy 也可以在单独的 @Bean方法上使用。

spring-test模块中的Spring的TestContext框架提供了 @ContextConfiguration注解,从Spring 3.1开始,该注解可以接受 @Configuration的数组类对象: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={AppConfig.class, DatabaseConfig.class}) public class MyTests { @Autowired MyBean myBean; @Autowired DataSource dataSource; @Test public void test() { // assertions against myBean ... } }

使用 @Enable注解启用内置的Spring功能,比如异步方法执行,定时任务执行,注释驱动的事务管理和SpringMVC类的Spring功能都可以启用和通过@Configuration类进行配置使用各自的“ @Enable”注释。
比如

org.springframework.scheduling.annotation.EnableAsync,@EnableAsync
org.springframework.scheduling.annotation.EnableScheduling @EnableScheduling,
org.springframework.transaction.annotation.EnableTransactionManagement @EnableTransactionManagement
org.springframework.context.annotation.EnableAspectJAutoProxy @EnableAspectJAutoProxy,
rg.springframework.web.servlet.config.annotation.EnableWebMvc @EnableWebMvc

@Configuration的约束
Configuration类必须作为类提供(即不作为从工厂方法返回的实例),以允许通过生成的子类增强运行时 配置类必须不是final。 配置类必须是非本地的(即,不能在方法中声明)。 任何嵌套的配置类都必须声明为static。 @Bean 方法不会再创建其他配置类(任何此类实例都将被视为常规Bean,其配置注释不会被检测到)。