68

SpringBoot入口类和@SpringBootApplication详解

 5 years ago
source link: http://www.choupangxia.com/topic/detail/136?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SpringBoot项目创建完成之后默认会生成一个*Application的入口类,通过该类的main方法即可启动SpringBoot项目。

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringbootRunApplication {

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

在此入口类中,我们可以看到SpringBoot创建的业务代码中(除单元测试)唯一的一个注解—— @SpringBootApplication ,这也是SpringBoot的核心注解。源代码如下:

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

    /**
     * 根据类排除不使用的自动配置
     */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    /**
     * 根据类名排除不使用的自动配置
     */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    String[] excludeName() default {};

    /**
     * 指定扫描的包
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    /**
     * 指定扫描的类
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

}

该注解自身为我们提供了四个可配置项:

  • exclude:根据类排除不使用的自动配置;
  • excludeName:根据类名排除不使用的自动配置;
  • scanBasePackages:扫描指定的包;
  • scanBasePackageClasses:扫描指定的类;

@SpringBootApplication 组合了 @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan ,因此我们也可以直接使用这三个注解来替代它。

在早期版本并没有 @SpringBootConfiguration ,之后使用了 @SpringBootConfiguration 并在其中组合了 @Configuration 注解。在 @EnableAutoConfiguration 注解中组合了 @AutoConfigurationPackage

@ComponentScan 相关使用

@ComponentScan 用来指定扫描的组建所在的包路径或class文件。在不指定参数的时候,SpringBoot的 @ComponentScan 默认会扫描同目录及同目录下级目录的类文件。通过部分源码我们可以明确的看到。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

    String resourcePattern() default “**/*.class";

    // 省略掉部分源码
}

上面的源码重点看一下属性resourcePattern的默认值“ */ .class”,可以看出,如果不指定其他参数的话,默认会去寻找同级目录下的class。

在构造SpringBoot项目时,往往会出现这样一种情况:因为忘记或不知道SpringBoot默认扫描的路径,随意创建包和类的位置,导致项目启动之后,无法实例化对应的组建,无法正确访问接口。

当然,如果是有意为之,那么我们就可以使用 @SpringBootApplication@ComponentScan 来指定一些特殊的需要实例化的包或类。

@SpringBootApplication(scanBasePackages = “com.secbro2.controller")
// 或
@ComponentScan(basePackages = "com.secbro2.controller")

@EnableAutoConfiguration

@EnableAutoConfiguration 让SpringBoot可以根据类路径中的jar包依赖可以为项目进行一些自动配置。这也是SpringBoot最核心的功能。当然,前提条件是依赖需要按照starter的规则来构建。

比如,我们添加了web的starter,那么SpringBoot就会自动添加Tomcat和SpringMVC的依赖,然后又会进行一些相应的默认配置。但有些依赖需要我们自己去配置一些内容,比如虽然引入了data-jpa的starter,但是如果我们不配置对应的数据源,程序肯定没办法正常启动。

关闭自动配置

自动配置有它的便捷之处,但在某些情况下,我们可能并不需要一些自动配置。比如,虽然引入了data-jpa的依赖,但此刻并不需要连接数据库。那么,就可以通过注解将此自动配置进行关闭。 @SpringBootApplication 为我们提供了相应的功能。

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

为什么是SpringBoot

面试中可能会被问到:为什么我们要使用SpringBoot?

你可能会说:因为SpringBoot用java配置替代了xml配置,或因为它内置Tomcat,可以直接打成jar包,通过java -jar快速启动等;但这都不是重点,重点是刚刚说的 @EnableAutoConfiguration 实现的功能:自动配置。基于编程的一个共识:约定优于配置。这也正是SpringBoot的核心。

回想一下,在使用SpringBoot的过程中,当用到某个组件,只需引入相应的依赖(starter)。此时SpringBoot已经帮我们把相关的依赖引入,配置好最基本的参数。然后我们根据需要再在application.yml文件中配置一些明确的参数(比如:数据库地址、用户名等),就完成了一个组件的集成,可以专注业务代码的编写了。

关注微信公众:程序新视界,回复“springbootrun”即可获得本篇内容PDF版本,更多免费资料,期待你的到来。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK