Hello everyone, I am early morning, before writing a lot of articles about SpringBoot, I believe that you have felt SpringBoot relative to the traditional Spring to bring convenient, so this article we will analyze the convenience of SpringBoot in the end convenient where
I don’t know if you’ve noticed, but when we create a SpringBoot project, we use the following startup class
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Copy the code
So in this article we’ll take a look at @SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}Copy the code
A: @ SpringBootConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}Copy the code
The @Configuration annotation is used to define a JavaConfig Configuration class that replaces an XML Configuration file. The annotated class contains one or more @bean annotated methods. These methods will be AnnotationConfigApplicationContext or AnnotationConfigWebApplicationContext scanned, and used to construct the bean definition, initialize the Spring container. This is the configuration recommended by the SpringBoot community.
- File structure
Traditional XML:
<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false"> </beans>Copy the code
Using the @ the Configuration:
@Configuration public class TestConfig { }Copy the code
- The definition of a bean
Traditional XML:
<bean id="testService" class="TestServiceImpl"> </bean>Copy the code
Using the @ the Configuration:
@Configuration public class TestConfig { @Bean public TestService testService() {returnnew TestServiceImpl(); }}Copy the code
2: @ ComponentScan
The basePackages attribute controls the scope of automatic scanning for @ComponentScan. If no scope is specified for @ComponentScan, the default scope is to scan from the package of the class in which @ComponentScan is declared.
3: @ EnableAutoConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class[] exclude() default {};
String[] excludeName() default {};
}Copy the code
@AutoConfigurationPackage
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import({Registrar.class}) public @interface AutoConfigurationPackage { }Copy the code
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}
public Set determineImports(AnnotationMetadata metadata) {
returnCollections.singleton(new AutoConfigurationPackages.PackageImport(metadata)); }}Copy the code
new PackageImport(metadata).getPackageName()
Returns the package components of the siblings and children of the current main program class.
This also proves that @ComponentScan scans the package of its class by default.
@Import({AutoConfigurationImportSelector.class})
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if(! this.isEnabled(annotationMetadata)) {return NO_IMPORTS;
} else {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }}Copy the code
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
if(! this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
returnnew AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); }}Copy the code
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}Copy the code
public static List loadFactoryNames(Class factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap result = (MultiValueMap)cache.get(classLoader);
if(result ! = null) {return result;
} else{ try { Enumeration urls = classLoader ! = null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); LinkedMultiValueMap result = new LinkedMultiValueMap(); / /... Omit the cache. The put (this, result);return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13); }}}Copy the code
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
......
}Copy the code
Take a look at the RedisProperties class
public class RedisProperties {
private int database = 0;
private String url;
private String host = "localhost"; private String password; private int port = 6379; private boolean ssl; private Duration timeout; private RedisProperties.Sentinel sentinel; private RedisProperties.Cluster cluster; private final RedisProperties.Jedis jedis = new RedisProperties.Jedis(); private final RedisProperties.Lettuce lettuce = new RedisProperties.Lettuce(); . Omit}Copy the code
Spring. Redis. Host = 127.0.0.1 spring. Redis. Port = 6379 spring. Redis. Timeout = 0 spring. Redis. Password =Copy the code
Four: the ending
@springBootApplication We’re done. In the next article we’ll look at the SpringApplication class
For springBoot do not know friends can see my springBoot series tutorial