Spring config java class

Basic Concepts: @Bean and @Configuration

The central artifacts in Spring’s Java configuration support are @Configuration -annotated classes and @Bean -annotated methods.

The @Bean annotation is used to indicate that a method instantiates, configures, and initializes a new object to be managed by the Spring IoC container. For those familiar with Spring’s XML configuration, the @Bean annotation plays the same role as the element. You can use @Bean -annotated methods with any Spring @Component . However, they are most often used with @Configuration beans.

Annotating a class with @Configuration indicates that its primary purpose is as a source of bean definitions. Furthermore, @Configuration classes let inter-bean dependencies be defined by calling other @Bean methods in the same class. The simplest possible @Configuration class reads as follows:

@Configuration public class AppConfig < @Bean public MyServiceImpl myService() < return new MyServiceImpl(); >>
@Configuration class AppConfig < @Bean fun myService(): MyServiceImpl < return MyServiceImpl() >>

The preceding AppConfig class is equivalent to the following Spring XML:

When @Bean methods are declared within classes that are not annotated with @Configuration , they are referred to as being processed in a “lite” mode. Bean methods declared in a @Component or even in a plain old class are considered to be “lite”, with a different primary purpose of the containing class and a @Bean method being a sort of bonus there. For example, service components may expose management views to the container through an additional @Bean method on each applicable component class. In such scenarios, @Bean methods are a general-purpose factory method mechanism.

Читайте также:  Compday ru configurator pc html

Unlike full @Configuration , lite @Bean methods cannot declare inter-bean dependencies. Instead, they operate on their containing component’s internal state and, optionally, on arguments that they may declare. Such a @Bean method should therefore not invoke other @Bean methods. Each such method is literally only a factory method for a particular bean reference, without any special runtime semantics. The positive side-effect here is that no CGLIB subclassing has to be applied at runtime, so there are no limitations in terms of class design (that is, the containing class may be final and so forth).

In common scenarios, @Bean methods are to be declared within @Configuration classes, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management. This prevents the same @Bean method from accidentally being invoked through a regular Java call, which helps to reduce subtle bugs that can be hard to track down when operating in “lite” mode.

The @Bean and @Configuration annotations are discussed in depth in the following sections. First, however, we cover the various ways of creating a spring container by using Java-based configuration.

Источник

Annotation Interface Configuration

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:

@Configuration public class AppConfig < @Bean public MyBean myBean() < // instantiate, configure and return bean . >>

Bootstrapping @Configuration classes

Via 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 XML

As an alternative to registering @Configuration classes directly against an AnnotationConfigApplicationContext , @Configuration classes may be declared as normal definitions within Spring XML files:

In the example above, 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 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:

@Configuration public 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 values

Using the Environment API

Externalized values may be looked up by injecting the Spring Environment into a @Configuration class — for example, using the @Autowired annotation:

@Configuration public class AppConfig < @Autowired Environment env; @Bean public 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; @Bean public MyBean myBean() < return new MyBean(env.getProperty("bean.name")); >>

See the Environment and @PropertySource javadocs for further details.

Using the @Value annotation

Externalized values may be injected into @Configuration classes using the @Value annotation:

@Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig < @Value("$") String beanName; @Bean public 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 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 classes

With the @Import annotation

@Configuration classes may be composed using the @Import annotation, similar to the way that 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:

@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()); >>

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") @Configuration public class EmbeddedDatabaseConfig < @Bean public DataSource dataSource() < // instantiate, configure and return embedded DataSource >> @Profile("production") @Configuration public class ProductionDatabaseConfig < @Bean public 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:

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

See the @Profile and Environment javadocs for further details.

With Spring XML using the @ImportResource annotation

As mentioned above, @Configuration classes may be declared as regular Spring 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 @Bean public MyBean myBean() < // inject the XML-defined dataSource bean return new MyBean(this.dataSource); >>

With nested @Configuration classes

@Configuration classes may be nested within one another as follows:

@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(); >> >

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 initialization

By 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 classes

The 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.

@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = ) class MyTests < @Autowired MyBean myBean; @Autowired DataSource dataSource; @Test void test() < // assertions against myBean . >>

See the TestContext framework reference documentation for details.

Enabling built-in Spring features using @Enable annotations

Spring 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 classes

  • Configuration 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).
  • Bean
  • Profile
  • Import
  • ImportResource
  • ComponentScan
  • Lazy
  • PropertySource
  • AnnotationConfigApplicationContext
  • ConfigurationClassPostProcessor
  • Environment
  • ContextConfiguration

Источник

Оцените статью