直接上文档吧,很方便!
Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example:@Configurationpublic class AppConfig {@Beanpublic MyBean myBean() {// instantiate, configure and return bean ...}}Bootstrapping @Configuration classesVia AnnotationConfigApplicationContext@Configuration classes are typically bootstrapped using either AnnotationConfigApplicationContext or its web-capable variant, AnnotationConfigWebApplicationContext. A simple example with the former follows:AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.register(AppConfig.class);ctx.refresh();MyBean myBean = ctx.getBean(MyBean.class);// use myBean ...See the AnnotationConfigApplicationContext javadocs for further details, and see AnnotationConfigWebApplicationContext for web configuration instructions in a Servlet container.Via Spring <beans> XMLAs an alternative to registering @Configuration classes directly against an AnnotationConfigApplicationContext, @Configuration classes may be declared as normal <bean> definitions within Spring XML files:<beans><context:annotation-config/><bean class="com.acme.AppConfig"/></beans>In the example above, <context:annotation-config/> is required in order to enable ConfigurationClassPostProcessor and other annotation-related post processors that facilitate handling @Configuration classes.Via component scanning@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning (typically using Spring XML's <context:component-scan/> element) and therefore may also take advantage of @Autowired/@Inject like any regular @Component. In particular, if a single constructor is present autowiring semantics will be applied transparently for that constructor:@Configurationpublic class AppConfig {private final SomeBean someBean;public AppConfig(SomeBean someBean) {this.someBean = someBean;}// @Bean definition using "SomeBean"}@Configuration classes may not only be bootstrapped using component scanning, but may also themselves configure component scanning using the @ComponentScan annotation:@Configuration@ComponentScan("com.acme.app.services")public class AppConfig {// various @Bean definitions ...}See the @ComponentScan javadocs for details.Working with externalized valuesUsing the Environment APIExternalized values may be looked up by injecting the Spring org.springframework.core.env.Environment into a @Configuration class — for example, using the @Autowired annotation:@Configurationpublic class AppConfig {@Autowired Environment env;@Beanpublic MyBean myBean() {MyBean myBean = new MyBean();myBean.setName(env.getProperty("bean.name"));return myBean;}}Properties resolved through the Environment reside in one or more "property source" objects, and @Configuration classes may contribute property sources to the Environment object using the @PropertySource annotation:@Configuration@PropertySource("classpath:/com/acme/app.properties")public class AppConfig {@Inject Environment env;@Beanpublic MyBean myBean() {return new MyBean(env.getProperty("bean.name"));}}See the Environment and @PropertySource javadocs for further details.Using the @Value annotationExternalized values may be injected into @Configuration classes using the @Value annotation:@Configuration@PropertySource("classpath:/com/acme/app.properties")public class AppConfig {@Value("${bean.name}") String beanName;@Beanpublic MyBean myBean() {return new MyBean(beanName);}}This approach is often used in conjunction with Spring's PropertySourcesPlaceholderConfigurer that can be enabled automatically in XML configuration via <context:property-placeholder/> or explicitly in a @Configuration class via a dedicated static @Bean method (see "a note on BeanFactoryPostProcessor-returning @Bean methods" of @Bean's javadocs for details). Note, however, that explicit registration of a PropertySourcesPlaceholderConfigurer via a static @Bean method is typically only required if you need to customize configuration such as the placeholder syntax, etc. Specifically, if no bean post-processor (such as a PropertySourcesPlaceholderConfigurer) has registered an embedded value resolver for the ApplicationContext, Spring will register a default embedded value resolver which resolves placeholders against property sources registered in the Environment. See the section below on composing @Configuration classes with Spring XML using @ImportResource; see the @Value javadocs; and see the @Bean javadocs for details on working with BeanFactoryPostProcessor types such as PropertySourcesPlaceholderConfigurer.Composing @Configuration classesWith the @Import annotation@Configuration classes may be composed using the @Import annotation, similar to the way that <import> works in Spring XML. Because @Configuration objects are managed as Spring beans within the container, imported configurations may be injected — for example, via constructor injection:@Configurationpublic class DatabaseConfig {@Beanpublic 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;}@Beanpublic MyBean myBean() {// reference the dataSource() bean methodreturn new MyBean(dataConfig.dataSource());}}Now both AppConfig and the imported DatabaseConfig can be bootstrapped by registering only AppConfig against the Spring context:new AnnotationConfigApplicationContext(AppConfig.class);With the @Profile annotation@Configuration classes may be marked with the @Profile annotation to indicate they should be processed only if a given profile or profiles are active:@Profile("development")@Configurationpublic class EmbeddedDatabaseConfig {@Beanpublic DataSource dataSource() {// instantiate, configure and return embedded DataSource}}@Profile("production")@Configurationpublic class ProductionDatabaseConfig {@Beanpublic DataSource dataSource() {// instantiate, configure and return production DataSource}}Alternatively, you may also declare profile conditions at the @Bean method level — for example, for alternative bean variants within the same configuration class:@Configurationpublic class ProfileDatabaseConfig {@Bean("dataSource")@Profile("development")public DataSource embeddedDatabase() { ... }@Bean("dataSource")@Profile("production")public DataSource productionDatabase() { ... }}See the @Profile and org.springframework.core.env.Environment javadocs for further details.With Spring XML using the @ImportResource annotationAs mentioned above, @Configuration classes may be declared as regular Spring <bean> definitions within Spring XML files. It is also possible to import Spring XML configuration files into @Configuration classes using the @ImportResource annotation. Bean definitions imported from XML can be injected — for example, using the @Inject annotation:@Configuration@ImportResource("classpath:/com/acme/database-config.xml")public class AppConfig {@Inject DataSource dataSource; // from XML@Beanpublic MyBean myBean() {// inject the XML-defined dataSource beanreturn new MyBean(this.dataSource);}}With nested @Configuration classes@Configuration classes may be nested within one another as follows:@Configurationpublic class AppConfig {@Inject DataSource dataSource;@Beanpublic MyBean myBean() {return new MyBean(dataSource);}@Configurationstatic class DatabaseConfig {@BeanDataSource dataSource() {return new EmbeddedDatabaseBuilder().build();}}}When bootstrapping such an arrangement, only AppConfig need be registered against the application context. By virtue of being a nested @Configuration class, DatabaseConfig will be registered automatically. This avoids the need to use an @Import annotation when the relationship between AppConfig and DatabaseConfig is already implicitly clear.Note also that nested @Configuration classes can be used to good effect with the @Profile annotation to provide two options of the same bean to the enclosing @Configuration class.Configuring lazy initializationBy default, @Bean methods will be eagerly instantiated at container bootstrap time. To avoid this, @Configuration may be used in conjunction with the @Lazy annotation to indicate that all @Bean methods declared within the class are by default lazily initialized. Note that @Lazy may be used on individual @Bean methods as well.Testing support for @Configuration classesThe Spring TestContext framework available in the spring-test module provides the @ContextConfiguration annotation which can accept an array of component class references — typically @Configuration or @Component classes.@RunWith(SpringRunner.class)@ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class})public class MyTests {@Autowired MyBean myBean;@Autowired DataSource dataSource;@Testpublic void test() {// assertions against myBean ...}}See the TestContext framework reference documentation for details.Enabling built-in Spring features using @Enable annotationsSpring features such as asynchronous method execution, scheduled task execution, annotation driven transaction management, and even Spring MVC can be enabled and configured from @Configuration classes using their respective "@Enable" annotations. See @EnableAsync, @EnableScheduling, @EnableTransactionManagement, @EnableAspectJAutoProxy, and @EnableWebMvc for details.Constraints when authoring @Configuration classesConfiguration classes must be provided as classes (i.e. not as instances returned from factory methods), allowing for runtime enhancements through a generated subclass.Configuration classes must be non-final (allowing for subclasses at runtime), unless the proxyBeanMethods flag is set to false in which case no runtime-generated subclass is necessary.Configuration classes must be non-local (i.e. may not be declared within a method).Any nested configuration classes must be declared as static.@Bean methods may not in turn create further configuration classes (any such instances will be treated as regular beans, with their configuration annotations remaining undetected).Since:3.0See Also:Bean, Profile, Import, ImportResource, ComponentScan, Lazy, PropertySource, AnnotationConfigApplicationContext, ConfigurationClassPostProcessor, org.springframework.core.env.Environment, org.springframework.test.context.ContextConfiguration@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Configuration {/*** Explicitly specify the name of the Spring bean definition associated with the* {@code @Configuration} class. If left unspecified (the common case), a bean* name will be automatically generated.* <p>The custom name applies only if the {@code @Configuration} class is picked* up via component scanning or supplied directly to an* {@link AnnotationConfigApplicationContext}. If the {@code @Configuration} class* is registered as a traditional XML bean definition, the name/id of the bean* element will take precedence.* @return the explicit component name, if any (or empty String otherwise)* @see AnnotationBeanNameGenerator*/@AliasFor(annotation = Component.class)String value() default "";/*** Specify whether {@code @Bean} methods should get proxied in order to enforce* bean lifecycle behavior, e.g. to return shared singleton bean instances even* in case of direct {@code @Bean} method calls in user code. This feature* requires method interception, implemented through a runtime-generated CGLIB* subclass which comes with limitations such as the configuration class and* its methods not being allowed to declare {@code final}.* <p>The default is {@code true}, allowing for 'inter-bean references' via direct* method calls within the configuration class as well as for external calls to* this configuration's {@code @Bean} methods, e.g. from another configuration class.* If this is not needed since each of this particular configuration's {@code @Bean}* methods is self-contained and designed as a plain factory method for container use,* switch this flag to {@code false} in order to avoid CGLIB subclass processing.* <p>Turning off bean method interception effectively processes {@code @Bean}* methods individually like when declared on non-{@code @Configuration} classes,* a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore* behaviorally equivalent to removing the {@code @Configuration} stereotype.* @since 5.2*/boolean proxyBeanMethods() default true;}
proxyBeanMethods表示是否为当前Configuration类生成一个CGLib代理,默认为true, 表示每次调用内部的@Bean方法时,直接返回容器里的单例bean,否则每次调用都会生成新的Bean实例。
举个例子:
@Configuration(proxyBeanMethods = false)@ConditionalOnProperty(prefix = "demo", name = "auto", havingValue = "true", matchIfMissing = false)public class DemoAutoConfiguration {public DemoAutoConfiguration() {System.out.println("##DemoAutoConfiguration##");}@Bean(name = "addr1")public AddressService addrService() {return new AddressService();}}
@Autowiredprivate DemoAutoConfiguration demoAutoConfiguration;@Autowired@Qualifier("addr1")private DemoAutoConfiguration.AddressService addressService1;public void run(ApplicationArguments args) throws Exception {DemoAutoConfiguration.AddressService addressService = demoAutoConfiguration.addrService();System.out.println(addressService == addressService1);}
如果proxyBeanMethods=false, 则demoAutoConfiguration.addrService()方法返回新的对象,与addressService1不一致,如果proxyBeanMethods=true,则每次调用demoAutoConfiguration.addrService()返回的对象为容器里的bean,与addressService1一致。
