@SpringBootApplication注解

Spring Boot入口类

当我们创建完成一个Spring Boot项目之后,会默认生成一个*Application的入口类,我们可以通过这个类中的main方法快速的启动一个Spring Boot项目。

@SpringBootApplication
public class MyTestApplication {
	public static void main(String[] args) {
		SpringApplication.run(MyTestApplication.class,args);
	}
}

@SpringBootApplication

在这个入口类中我们可以发现一个@SpringBootApplication注解,这个注解也是Spring Boot中的核心注解。

@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 {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 根据类型排除指定的自动配置类
	 *
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 根据类名排除指定的自动配置类
	 *
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	/**
	 * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
	 * for a type-safe alternative to String-based package names.
	 * <p>
	 * <strong>Note:</strong> this setting is an alias for
	 * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
	 * scanning or Spring Data {@link Repository} scanning. For those you should add
	 * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
	 * {@code @Enable...Repositories} annotations.
	 *   扫描指定路径下的包
	 * @return base packages to scan
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	/**
	 * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
	 * scan for annotated components. The package of each class specified will be scanned.
	 * <p>
	 * Consider creating a special no-op marker class or interface in each package that
	 * serves no purpose other than being referenced by this attribute.
	 * <p>
	 * <strong>Note:</strong> this setting is an alias for
	 * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
	 * scanning or Spring Data {@link Repository} scanning. For those you should add
	 * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
	 * {@code @Enable...Repositories} annotations.
	 *  扫描指定的类
	 * @return base packages to scan
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

}

根据@SpringBootApplication注解的源码我们可以得知,该注解为我们提供了四个配置项:

1.exclude:根据类排除不使用的自动装配
2.excludeName:根据类民排除不是用的自动装配
3.scanBasePackages:扫描指定包下的类
4.scanBasePackageClasses:扫描指定的类

接下来我们可以看到SpringBootApplication注解中组合了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解,因此我们可以使用这三个注解来代替@SpringBootApplication注解。

@SpringBootConfiguration


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
 
}

从上述源码中可以看到,@SpringBootConfiguration注解是@Configuration的派生注解。和@Configuration的功能一致,标注当前类是一个配置类,不过@SpringBootConfiguration是Spring boot的注解而@Configuration是spring的注解

@EnableAutoConfiguration

从这个注解的名字我们就可以看到它的作用是开启自动配置。
那么就引申出来几个问题,

  1. 什么是自动配置?
  2. 自动配置帮助我们解决了什么问题?
  3. 它是怎么做到的?
  4. 这么做有什么优点或缺点?

凡是学过Spring的同学,肯定都知道当我们使用Spring开发的时候,往往会使用大量的XML进行相关配置。虽然Spring在之后的版本中提出了使用注解和Java的方式简化配置。但是还是会伴随着大量的配置。

所以在我们的Spring Boot中通过实现自动配置来做到约定大于配置,其实自动配置也就是实现大多数用户平时习惯的配置作为默认配置。这也就回答了上述1,2两个问题。

接下来我们看一下Sprint boot是如何做的。

自动配置原理 :

  1. Spring Boot在启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration。

  2. @EnableAutoConfiguration作用:

    • 利用AutoConfigurationImportSelector给容器中导入一些组件。

    • 在AutoConfigurationImportSelector实现了ImportSelector接口的selectImport方法

    • List configurations = getCandidateConfigurations(annotationMetadata, attributes);//这个方法为了获取获选的配置

      • List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
        getBeanClassLoader());
      • 扫描所有jar包类路径下的META-INF/spring.factories
      • 把扫描到的文件的内容包装成一个properties对象
      • 然后从properties对象中获取EnableAutoConfiguration.class类(类名)对应的值,然后添加到容器中
    • 总结一下就是将类路径下的META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中。

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
    
  3. 在配置文件中有许多这种**AutoConfiguration,每一个都是容器中的一个组件,用这些自动配置类开始自动配置。

  4. 接下来我们就以org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration为例,看看自动配置的原理:

@Configuration //表明这是一个配置累
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) //自动配置的优先级,将
@ConditionalOnClass(ServletRequest.class)//判断当前项目中是否有ServletRequest这个类
@ConditionalOnWebApplication(type = Type.SERVLET)//Spring底层的@Conditional注解,根据不同的条件,如果满足条件配置才会生效。
//那么当前这个注解就是判断当前应用是否是web应用,如果是则启用
@EnableConfigurationProperties(ServerProperties.class)//启动指定类的configurationProperties功能
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {

    //  给容器中添加组件
    @Bean
	public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
		return new ServletWebServerFactoryCustomizer(serverProperties);
	}

根据当前不同的环境来决定当前配置累是否生效。

一旦配置类生效:这个配置类就会给容器中添加各种组件;这些组件的属性都是从对应的properties类中获取,这些类中的属性又是和配置文件绑定的。

5.我们所有在配置文件中可以配置的属性都是在XxxxProperties中封装着;所以如果我们想知道配置文件中可以配置哪些类就可以通过查看XxxxProperties类。

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
小总结
  1. SpringBoot启动时会加载大量的配置类
  2. 我们首先可以看一下需要的功能SpringBoot有没有写好默认的配置
  3. 然后我们可以看看这个配置类中到底配置了哪些组件;(只要有默认的我们就不需要重新配置)
  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某属性,我们就可以在配置文件中指定这些属性的值。

xxxxAutoConfiguration:自动配置类,给容器中添加组件
xxxxProperties:封装配置文件中的相关属性。

以上就是SpringBoot针对自动配置所做的一些事情。

那么这么做有什么好处呢?

自动配置最主要的好处就是将程序开发人员从复杂的XML配置中解放出来,通过默认配置的方式,让开发人员更加关注于业务代码。同时也支持配置文件中属性的修改,可以满足特殊性需求,增加灵活性。

@ComponentScan

这个注解我们在Spring中就已经见过了,它的作用主要就是扫描当前类所在的包下的所有配置类,将这些配置类注入到IOC容器中。

规定之后标注了@Controller、@Service、@Repository,@Component这四个注解的类会自动注入到IOC容器中。

当然,不仅仅只有这四个注解可以被扫描到,ComponentScan根据名字我们首先想到的是扫描component,那么为什么被@Service等注解标注的类也同样可以被扫描到。

点开这些可以被扫描的注解,我们会发现这些注解都直接或间接的被@Component注解标注。由于Annotation被允许被继承,没有派生子类的能力,因此Spring Framework采用元注解的方式实现直接之间的“派生”

@ComponentScan注解的作用主要是扫描,同时也具有过滤和排除过滤。

  1. ComponentScan.Filter[] includeFilters() default{}: 按照某些规则排除组件。
  2. ComponentScan.Filter[] encludeFilters() default{};指定扫描的时候只需要包含哪些组件。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值