@SpringBootApplication
这个注解是加在启动类上的:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
源码:
package org.springframework.boot.autoconfigure;
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
@java.lang.annotation.Inherited
@org.springframework.boot.SpringBootConfiguration
@org.springframework.boot.autoconfigure.EnableAutoConfiguration
@org.springframework.context.annotation.ComponentScan(excludeFilters = {@org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.context.TypeExcludeFilter.class}), @org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication {
@org.springframework.core.annotation.AliasFor(annotation = org.springframework.boot.autoconfigure.EnableAutoConfiguration.class, attribute = "exclude")
java.lang.Class<?>[] exclude() default {};
@org.springframework.core.annotation.AliasFor(annotation = org.springframework.boot.autoconfigure.EnableAutoConfiguration.class, attribute = "excludeName")
java.lang.String[] excludeName() default {};
@org.springframework.core.annotation.AliasFor(annotation = org.springframework.context.annotation.ComponentScan.class, attribute = "basePackages")
java.lang.String[] scanBasePackages() default {};
@org.springframework.core.annotation.AliasFor(annotation = org.springframework.context.annotation.ComponentScan.class, attribute = "basePackageClasses")
java.lang.Class<?>[] scanBasePackageClasses() default {};
}
@SpringBootApplication等同于 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan 这三个注解:
- @SpringBootConfiguration: 在springboot项目中替代@Configuration, 等同于原来xml下面的<beans></beans>, 在标记了此标签的类的方法标记 @Bean 可以在容器启动的时候调用这个方法注入一个bean, @Bean等同于xml 的 <bean></bean>标签。
/**
* @author: zenghong
* @Date: 2019/3/14 11:43
* @Description: restTemplate配置
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder)
{ //连接时间2s,数据读取时间10s
return restTemplateBuilder.setConnectTimeout(Duration.ofSeconds(2))
.setReadTimeout(Duration.ofSeconds(30))
.build();
}
}
- @ComponentScan 这个注解完成的是自动扫描的功能,相当于Spring XML配置文件中的:<context:component-scan>,可以使用basePackages属性指定要扫描的包,以及扫描的条件。如果不设置的话默认扫描@ComponentScan注解所在类的同级类和同级目录下的所有类,所以对于一个Spring Boot项目,一般会把入口类放在顶层目录中,这样就能够保证源码目录下的所有类都能够被扫描到。
- @EnableAutoConfiguration : 开启自动配置。源码:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
通过@EnableAutoConfiguration,spring会去 META-INF/spring.factories 中去读取默认配置(注意,所有jar包的 META-INF/spring.factories都会被读取,这意味着我们可以自定义扩展)。@Import注解作用是通过导入的方式吧bean加入到springIOC容器中,支持Configuration,ImportSelector,ImportBeanDefinitionRegistrar三种类型,这里使用的ImportSelector。
比如在spring-boot-autoconfigure jar包下的 META-INF/spring.factories 的部分代码如下:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
这里定义了自动配置的各个实现类,比如 WebMvcAutoConfiguration ,我们去看看源码:
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = { "/" };
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = true)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Bean
@ConditionalOnMissingBean(FormContentFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter", name = "enabled", matchIfMissing = true)
public OrderedFormContentFilter formContentFilter() {
return new OrderedFormContentFilter();
}
这个类代码太长,截了上面一部分,重点这是一个@Configuration类,通过@Bean注入类来完成框架配置,其中会有一些默认值, 比如
SERVLET_LOCATIONS = { "/" }
表示当您不配置sevlet的访问路径的时候,默认是根路径。
网友评论