001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.context.annotation; 018 019import java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Retention; 022import java.lang.annotation.RetentionPolicy; 023import java.lang.annotation.Target; 024 025import org.springframework.beans.factory.annotation.Autowired; 026import org.springframework.beans.factory.annotation.Value; 027import org.springframework.stereotype.Component; 028 029/** 030 * Indicates that a class declares one or more {@link Bean @Bean} methods and 031 * may be processed by the Spring container to generate bean definitions and 032 * service requests for those beans at runtime, for example: 033 * 034 * <pre class="code"> 035 * @Configuration 036 * public class AppConfig { 037 * 038 * @Bean 039 * public MyBean myBean() { 040 * // instantiate, configure and return bean ... 041 * } 042 * }</pre> 043 * 044 * <h2>Bootstrapping {@code @Configuration} classes</h2> 045 * 046 * <h3>Via {@code AnnotationConfigApplicationContext}</h3> 047 * 048 * <p>{@code @Configuration} classes are typically bootstrapped using either 049 * {@link AnnotationConfigApplicationContext} or its web-capable variant, 050 * {@link org.springframework.web.context.support.AnnotationConfigWebApplicationContext 051 * AnnotationConfigWebApplicationContext}. A simple example with the former follows: 052 * 053 * <pre class="code"> 054 * AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 055 * ctx.register(AppConfig.class); 056 * ctx.refresh(); 057 * MyBean myBean = ctx.getBean(MyBean.class); 058 * // use myBean ... 059 * </pre> 060 * 061 * <p>See the {@link AnnotationConfigApplicationContext} javadocs for further details, and see 062 * {@link org.springframework.web.context.support.AnnotationConfigWebApplicationContext 063 * AnnotationConfigWebApplicationContext} for web configuration instructions in a 064 * {@code Servlet} container. 065 * 066 * <h3>Via Spring {@code <beans>} XML</h3> 067 * 068 * <p>As an alternative to registering {@code @Configuration} classes directly against an 069 * {@code AnnotationConfigApplicationContext}, {@code @Configuration} classes may be 070 * declared as normal {@code <bean>} definitions within Spring XML files: 071 * 072 * <pre class="code"> 073 * <beans> 074 * <context:annotation-config/> 075 * <bean class="com.acme.AppConfig"/> 076 * </beans> 077 * </pre> 078 * 079 * <p>In the example above, {@code <context:annotation-config/>} is required in order to 080 * enable {@link ConfigurationClassPostProcessor} and other annotation-related 081 * post processors that facilitate handling {@code @Configuration} classes. 082 * 083 * <h3>Via component scanning</h3> 084 * 085 * <p>{@code @Configuration} is meta-annotated with {@link Component @Component}, therefore 086 * {@code @Configuration} classes are candidates for component scanning (typically using 087 * Spring XML's {@code <context:component-scan/>} element) and therefore may also take 088 * advantage of {@link Autowired @Autowired}/{@link javax.inject.Inject @Inject} 089 * like any regular {@code @Component}. In particular, if a single constructor is present 090 * autowiring semantics will be applied transparently for that constructor: 091 * 092 * <pre class="code"> 093 * @Configuration 094 * public class AppConfig { 095 * 096 * private final SomeBean someBean; 097 * 098 * public AppConfig(SomeBean someBean) { 099 * this.someBean = someBean; 100 * } 101 * 102 * // @Bean definition using "SomeBean" 103 * 104 * }</pre> 105 * 106 * <p>{@code @Configuration} classes may not only be bootstrapped using 107 * component scanning, but may also themselves <em>configure</em> component scanning using 108 * the {@link ComponentScan @ComponentScan} annotation: 109 * 110 * <pre class="code"> 111 * @Configuration 112 * @ComponentScan("com.acme.app.services") 113 * public class AppConfig { 114 * // various @Bean definitions ... 115 * }</pre> 116 * 117 * <p>See the {@link ComponentScan @ComponentScan} javadocs for details. 118 * 119 * <h2>Working with externalized values</h2> 120 * 121 * <h3>Using the {@code Environment} API</h3> 122 * 123 * <p>Externalized values may be looked up by injecting the Spring 124 * {@link org.springframework.core.env.Environment} into a {@code @Configuration} 125 * class — for example, using the {@code @Autowired} annotation: 126 * 127 * <pre class="code"> 128 * @Configuration 129 * public class AppConfig { 130 * 131 * @Autowired Environment env; 132 * 133 * @Bean 134 * public MyBean myBean() { 135 * MyBean myBean = new MyBean(); 136 * myBean.setName(env.getProperty("bean.name")); 137 * return myBean; 138 * } 139 * }</pre> 140 * 141 * <p>Properties resolved through the {@code Environment} reside in one or more "property 142 * source" objects, and {@code @Configuration} classes may contribute property sources to 143 * the {@code Environment} object using the {@link PropertySource @PropertySource} 144 * annotation: 145 * 146 * <pre class="code"> 147 * @Configuration 148 * @PropertySource("classpath:/com/acme/app.properties") 149 * public class AppConfig { 150 * 151 * @Inject Environment env; 152 * 153 * @Bean 154 * public MyBean myBean() { 155 * return new MyBean(env.getProperty("bean.name")); 156 * } 157 * }</pre> 158 * 159 * <p>See the {@link org.springframework.core.env.Environment Environment} 160 * and {@link PropertySource @PropertySource} javadocs for further details. 161 * 162 * <h3>Using the {@code @Value} annotation</h3> 163 * 164 * <p>Externalized values may be injected into {@code @Configuration} classes using 165 * the {@link Value @Value} annotation: 166 * 167 * <pre class="code"> 168 * @Configuration 169 * @PropertySource("classpath:/com/acme/app.properties") 170 * public class AppConfig { 171 * 172 * @Value("${bean.name}") String beanName; 173 * 174 * @Bean 175 * public MyBean myBean() { 176 * return new MyBean(beanName); 177 * } 178 * }</pre> 179 * 180 * <p>This approach is often used in conjunction with Spring's 181 * {@link org.springframework.context.support.PropertySourcesPlaceholderConfigurer 182 * PropertySourcesPlaceholderConfigurer} that can be enabled <em>automatically</em> 183 * in XML configuration via {@code <context:property-placeholder/>} or <em>explicitly</em> 184 * in a {@code @Configuration} class via a dedicated {@code static} {@code @Bean} method 185 * (see "a note on BeanFactoryPostProcessor-returning {@code @Bean} methods" of 186 * {@link Bean @Bean}'s javadocs for details). Note, however, that explicit registration 187 * of a {@code PropertySourcesPlaceholderConfigurer} via a {@code static} {@code @Bean} 188 * method is typically only required if you need to customize configuration such as the 189 * placeholder syntax, etc. Specifically, if no bean post-processor (such as a 190 * {@code PropertySourcesPlaceholderConfigurer}) has registered an <em>embedded value 191 * resolver</em> for the {@code ApplicationContext}, Spring will register a default 192 * <em>embedded value resolver</em> which resolves placeholders against property sources 193 * registered in the {@code Environment}. See the section below on composing 194 * {@code @Configuration} classes with Spring XML using {@code @ImportResource}; see 195 * the {@link Value @Value} javadocs; and see the {@link Bean @Bean} javadocs for details 196 * on working with {@code BeanFactoryPostProcessor} types such as 197 * {@code PropertySourcesPlaceholderConfigurer}. 198 * 199 * <h2>Composing {@code @Configuration} classes</h2> 200 * 201 * <h3>With the {@code @Import} annotation</h3> 202 * 203 * <p>{@code @Configuration} classes may be composed using the {@link Import @Import} annotation, 204 * similar to the way that {@code <import>} works in Spring XML. Because 205 * {@code @Configuration} objects are managed as Spring beans within the container, 206 * imported configurations may be injected — for example, via constructor injection: 207 * 208 * <pre class="code"> 209 * @Configuration 210 * public class DatabaseConfig { 211 * 212 * @Bean 213 * public DataSource dataSource() { 214 * // instantiate, configure and return DataSource 215 * } 216 * } 217 * 218 * @Configuration 219 * @Import(DatabaseConfig.class) 220 * public class AppConfig { 221 * 222 * private final DatabaseConfig dataConfig; 223 * 224 * public AppConfig(DatabaseConfig dataConfig) { 225 * this.dataConfig = dataConfig; 226 * } 227 * 228 * @Bean 229 * public MyBean myBean() { 230 * // reference the dataSource() bean method 231 * return new MyBean(dataConfig.dataSource()); 232 * } 233 * }</pre> 234 * 235 * <p>Now both {@code AppConfig} and the imported {@code DatabaseConfig} can be bootstrapped 236 * by registering only {@code AppConfig} against the Spring context: 237 * 238 * <pre class="code"> 239 * new AnnotationConfigApplicationContext(AppConfig.class);</pre> 240 * 241 * <h3>With the {@code @Profile} annotation</h3> 242 * 243 * <p>{@code @Configuration} classes may be marked with the {@link Profile @Profile} annotation to 244 * indicate they should be processed only if a given profile or profiles are <em>active</em>: 245 * 246 * <pre class="code"> 247 * @Profile("development") 248 * @Configuration 249 * public class EmbeddedDatabaseConfig { 250 * 251 * @Bean 252 * public DataSource dataSource() { 253 * // instantiate, configure and return embedded DataSource 254 * } 255 * } 256 * 257 * @Profile("production") 258 * @Configuration 259 * public class ProductionDatabaseConfig { 260 * 261 * @Bean 262 * public DataSource dataSource() { 263 * // instantiate, configure and return production DataSource 264 * } 265 * }</pre> 266 * 267 * <p>Alternatively, you may also declare profile conditions at the {@code @Bean} method level 268 * — for example, for alternative bean variants within the same configuration class: 269 * 270 * <pre class="code"> 271 * @Configuration 272 * public class ProfileDatabaseConfig { 273 * 274 * @Bean("dataSource") 275 * @Profile("development") 276 * public DataSource embeddedDatabase() { ... } 277 * 278 * @Bean("dataSource") 279 * @Profile("production") 280 * public DataSource productionDatabase() { ... } 281 * }</pre> 282 * 283 * <p>See the {@link Profile @Profile} and {@link org.springframework.core.env.Environment} 284 * javadocs for further details. 285 * 286 * <h3>With Spring XML using the {@code @ImportResource} annotation</h3> 287 * 288 * <p>As mentioned above, {@code @Configuration} classes may be declared as regular Spring 289 * {@code <bean>} definitions within Spring XML files. It is also possible to 290 * import Spring XML configuration files into {@code @Configuration} classes using 291 * the {@link ImportResource @ImportResource} annotation. Bean definitions imported from 292 * XML can be injected — for example, using the {@code @Inject} annotation: 293 * 294 * <pre class="code"> 295 * @Configuration 296 * @ImportResource("classpath:/com/acme/database-config.xml") 297 * public class AppConfig { 298 * 299 * @Inject DataSource dataSource; // from XML 300 * 301 * @Bean 302 * public MyBean myBean() { 303 * // inject the XML-defined dataSource bean 304 * return new MyBean(this.dataSource); 305 * } 306 * }</pre> 307 * 308 * <h3>With nested {@code @Configuration} classes</h3> 309 * 310 * <p>{@code @Configuration} classes may be nested within one another as follows: 311 * 312 * <pre class="code"> 313 * @Configuration 314 * public class AppConfig { 315 * 316 * @Inject DataSource dataSource; 317 * 318 * @Bean 319 * public MyBean myBean() { 320 * return new MyBean(dataSource); 321 * } 322 * 323 * @Configuration 324 * static class DatabaseConfig { 325 * @Bean 326 * DataSource dataSource() { 327 * return new EmbeddedDatabaseBuilder().build(); 328 * } 329 * } 330 * }</pre> 331 * 332 * <p>When bootstrapping such an arrangement, only {@code AppConfig} need be registered 333 * against the application context. By virtue of being a nested {@code @Configuration} 334 * class, {@code DatabaseConfig} <em>will be registered automatically</em>. This avoids 335 * the need to use an {@code @Import} annotation when the relationship between 336 * {@code AppConfig} and {@code DatabaseConfig} is already implicitly clear. 337 * 338 * <p>Note also that nested {@code @Configuration} classes can be used to good effect 339 * with the {@code @Profile} annotation to provide two options of the same bean to the 340 * enclosing {@code @Configuration} class. 341 * 342 * <h2>Configuring lazy initialization</h2> 343 * 344 * <p>By default, {@code @Bean} methods will be <em>eagerly instantiated</em> at container 345 * bootstrap time. To avoid this, {@code @Configuration} may be used in conjunction with 346 * the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared 347 * within the class are by default lazily initialized. Note that {@code @Lazy} may be used 348 * on individual {@code @Bean} methods as well. 349 * 350 * <h2>Testing support for {@code @Configuration} classes</h2> 351 * 352 * <p>The Spring <em>TestContext framework</em> available in the {@code spring-test} module 353 * provides the {@code @ContextConfiguration} annotation which can accept an array of 354 * <em>component class</em> references — typically {@code @Configuration} or 355 * {@code @Component} classes. 356 * 357 * <pre class="code"> 358 * @RunWith(SpringRunner.class) 359 * @ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class}) 360 * public class MyTests { 361 * 362 * @Autowired MyBean myBean; 363 * 364 * @Autowired DataSource dataSource; 365 * 366 * @Test 367 * public void test() { 368 * // assertions against myBean ... 369 * } 370 * }</pre> 371 * 372 * <p>See the 373 * <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-framework">TestContext framework</a> 374 * reference documentation for details. 375 * 376 * <h2>Enabling built-in Spring features using {@code @Enable} annotations</h2> 377 * 378 * <p>Spring features such as asynchronous method execution, scheduled task execution, 379 * annotation driven transaction management, and even Spring MVC can be enabled and 380 * configured from {@code @Configuration} classes using their respective "{@code @Enable}" 381 * annotations. See 382 * {@link org.springframework.scheduling.annotation.EnableAsync @EnableAsync}, 383 * {@link org.springframework.scheduling.annotation.EnableScheduling @EnableScheduling}, 384 * {@link org.springframework.transaction.annotation.EnableTransactionManagement @EnableTransactionManagement}, 385 * {@link org.springframework.context.annotation.EnableAspectJAutoProxy @EnableAspectJAutoProxy}, 386 * and {@link org.springframework.web.servlet.config.annotation.EnableWebMvc @EnableWebMvc} 387 * for details. 388 * 389 * <h2>Constraints when authoring {@code @Configuration} classes</h2> 390 * 391 * <ul> 392 * <li>Configuration classes must be provided as classes (i.e. not as instances returned 393 * from factory methods), allowing for runtime enhancements through a generated subclass. 394 * <li>Configuration classes must be non-final. 395 * <li>Configuration classes must be non-local (i.e. may not be declared within a method). 396 * <li>Any nested configuration classes must be declared as {@code static}. 397 * <li>{@code @Bean} methods may not in turn create further configuration classes 398 * (any such instances will be treated as regular beans, with their configuration 399 * annotations remaining undetected). 400 * </ul> 401 * 402 * @author Rod Johnson 403 * @author Chris Beams 404 * @since 3.0 405 * @see Bean 406 * @see Profile 407 * @see Import 408 * @see ImportResource 409 * @see ComponentScan 410 * @see Lazy 411 * @see PropertySource 412 * @see AnnotationConfigApplicationContext 413 * @see ConfigurationClassPostProcessor 414 * @see org.springframework.core.env.Environment 415 * @see org.springframework.test.context.ContextConfiguration 416 */ 417@Target(ElementType.TYPE) 418@Retention(RetentionPolicy.RUNTIME) 419@Documented 420@Component 421public @interface Configuration { 422 423 /** 424 * Explicitly specify the name of the Spring bean definition associated with the 425 * {@code @Configuration} class. If left unspecified (the common case), a bean 426 * name will be automatically generated. 427 * <p>The custom name applies only if the {@code @Configuration} class is picked 428 * up via component scanning or supplied directly to an 429 * {@link AnnotationConfigApplicationContext}. If the {@code @Configuration} class 430 * is registered as a traditional XML bean definition, the name/id of the bean 431 * element will take precedence. 432 * @return the explicit component name, if any (or empty String otherwise) 433 * @see AnnotationBeanNameGenerator 434 */ 435 String value() default ""; 436 437}