The spring boot annotations are mostly placed in org.springframework.boot.autoconfigure
and org.springframework.boot.autoconfigure.condition
packages.
@SpringBootApplication
Spring boot is mostly about auto-configuration. This auto-configuration is done by component scanning i.e. finding all classes in classspath for @Component
annotation. It also involve scanning of @Configuration
annotation and initialize some extra beans.
@SpringBootApplication
annotation enable all able things in one step. It enables the three features:
@EnableAutoConfiguration
: enable auto-configuration mechanism @ComponentScan
: enable @Component scan @SpringBootConfiguration
: register extra beans in the context
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }
@EnableAutoConfiguration
This annotation enables auto-configuration of the Spring Application Context, attempting to guess and configure beans that we are likely to need based on the presence of predefined classes in classpath.
For example, if we have tomcat-embedded.jar on the classpath, we are likely to want a TomcatServletWebServerFactory
.
Auto-configuration classes are regular Spring Configuration beans.
Auto-configuration classes are usually applied based on your classpath and what beans you have defined.
They are located using the SpringFactoriesLoader
mechanism (keyed against this class).
Generally auto-configuration beans are @Conditional
beans (most often using @ConditionalOnClass
and @ConditionalOnMissingBean
annotations).
You can always manually exclude any configuration that you never want to apply using two methods –
i) Use excludeName()
ii) Using the spring.autoconfigure.exclude
property in properties file. e.g.
@EnableAutoConfiguration(excludeName = {"multipartResolver","mbeanServer"})
@ComponentScan
This annotation provides support parallel with Spring XML's context:component-scan
element.
Either basePackageClasses()
or basePackages()
may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
@SpringBootConfiguration
@SpringBootConfiguration is new annotation in Spring boot 2. Previously, we have been using @Configuration annotation. You can use @Configuration
in place of this. Both are same thing.
It indicates that a class provides Spring Boot application @Configuration
. It simply means that annotated class is a configuration class and shall be scanned for further configurations and bean definitions.
It can be used as an alternative to the Spring's standard @Configuration
annotation so that configuration can be found automatically.
Application should only ever include one @SpringBootConfiguration
and most idiomatic Spring Boot applications will inherit it from @SpringBootApplication
.
The main difference is both annotations is that @SpringBootConfiguration
allows configuration to be automatically located. This can be especially useful for unit or integration tests.
@SpringBootApplication -------> @SpringBootConfiguration -------> @Configuration
@ImportAutoConfiguration
It import and apply only the specified auto-configuration classes.
The difference between @
ImportAutoConfiguration
and @
EnableAutoConfiguration
is that later attempts to configure beans that are found in the class path during scanning, whereas @ImportAutoConfiguration
only runs the configuration classes that we provide in the annotation.
We should use @ImportAutoConfiguration
when we don't want to enable the default auto-configuration.
ComponentScan("path.to.your.controllers") @ImportAutoConfiguration({ WebMvcAutoConfiguration.class ,DispatcherServletAutoConfiguration.class ,EmbeddedServletContainerAutoConfiguration.class ,ServerPropertiesAutoConfiguration.class ,HttpMessageConvertersAutoConfiguration.class}) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); }
@AutoConfigureBefore, @AutoConfigureAfter, @AutoConfigureOrder
We can use the @
AutoConfigureAfter
or @
AutoConfigureBefore
annotations if our configuration needs to be applied in a specific order (before of after).
If we want to order certain auto-configurations that should not have any direct knowledge of each other, we can also use @AutoConfigureOrder
. That annotation has the same semantic as the regular @Order
annotation but provides a dedicated order for auto-configuration classes.
@Configuration @AutoConfigureAfter(CacheAutoConfiguration.class) @ConditionalOnBean(CacheManager.class) @ConditionalOnClass(CacheStatisticsProvider.class) public class RedissonCacheStatisticsAutoConfiguration { @Bean public RedissonCacheStatisticsProvider redissonCacheStatisticsProvider(){ return new RedissonCacheStatisticsProvider(); } }
Condition Annotations
All auto-configuration classes generally have one or more @Conditional
annotations.
It allow to register a bean only when the condition meets.
Following are some useful conditional annotations to use.
@ConditionalOnBean and @ConditionalOnMissingBean
These annotations let a bean be included based on the presence or absence of specific beans.
It's value
attribute is used to specify beans by type or by name
. Also the search
attribute lets us limit the ApplicationContext
hierarchy that should be considered when searching for beans.
Using these annotations at the class level prevents registration of the @Configuration
class as a bean if the condition does not match.
In below example, bean JpaTransactionManager
will only be loaded if a bean of type JpaTransactionManager
is not already defined in the application context.
@Bean @ConditionalOnMissingBean(type = "JpaTransactionManager") JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory); return transactionManager; }
@ConditionalOnClass and @ConditionalOnMissingClass
These annotations let configuration classes be included based on the presence or absence of specific classes.
Notice that annotation metadata is parsed by using spring ASM module, and even if a class might not be present in runtime – you can still refer to the class in annotation.
We can also use value
attribute to refer the real class or the name
attribute to specify the class name by using a String value.
Below configuration will create EmbeddedAcmeService
only if this class is available in runtime and no other bean with same name is present in application context.
@Configuration @ConditionalOnClass(EmbeddedAcmeService.class) static class EmbeddedConfiguration { @Bean @ConditionalOnMissingBean public EmbeddedAcmeService embeddedAcmeService() { ... } }
@ConditionalOnNotWebApplication and @ConditionalOnWebApplication
These annotations let configuration be included depending on whether the application is a "web application" or not.
In Spring, a web application is one which meets at least one of below three requirements:
- uses a Spring
WebApplicationContext
- defines a
session
scope - has a
StandardServletEnvironment
@ConditionalOnProperty
This annotation lets configuration be included based on the presence and value of a Spring Environment property.
For example, if we have different datasource definitions for different environments, we can use this annotation.
Bean @ConditionalOnProperty(name = "env", havingValue = "local") DataSource dataSource() { // ... } @Bean @ConditionalOnProperty(name = "env", havingValue = "prod") DataSource dataSource() { // ... }
@ConditionalOnResource
This annotation lets configuration be included only when a specific resource is present in the classpath.
Resources can be specified by using the usual Spring conventions.
@ConditionalOnResource(resources = "classpath:vendor.properties") Properties additionalProperties() { // ... }
@ConditionalOnExpression
This annotation lets configuration be included based on the result of a SpEL expression. Use this annotation when condition to evaluate is complex one and shall be evaluated as one condition.
@Bean @ConditionalOnExpression("${env} && ${havingValue == 'local'}") DataSource dataSource() { // ... }
@ConditionalOnCloudPlatform
This annotation lets configuration be included when the specified cloud platform is active.
@Configuration @ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) public class CloudConfigurationExample { @Bean public MyBean myBean(MyProperties properties) { return new MyBean(properties.getParam); } }
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.