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