第三章 springboot -- 第一节 SpringBoot启动注解 ( @SpringBootApplication )

本文主要是介绍第三章 springboot -- 第一节 SpringBoot启动注解 ( @SpringBootApplication ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SpringBoot 启动注解 @SpringBootApplication 相关知识整理

一、启动类使用

我们可以通过SpringBoot官方网站 https://start.spring.io/创建一个基础的SpringBoot项目
如下示例为 tysite-spark 项目的启动类部分代码

package org.items.tysite;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;@SpringBootApplication  (1)
public class StartApplication extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(StartApplication.class);}public static void main(String[] args) {SpringApplication.run(StartApplication.class, args);}
}

本章节主要介绍 @SpringBootApplication 注解的都做了那些事情,前面的文章已经介绍过注解的基础知识,本文将忽略基础知识部分的讲解

二、@SpringBootApplication 详解

@SpringBootApplication注解,主要包含@SpringBootConfiguration 、@EnableAutoConfiguration 和@ComponentScan 三个注解

注解源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration    (1)
@EnableAutoConfiguration    (2)
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })    (3)
public @interface SpringBootApplication {
……
}

(1)@SpringBootConfiguration: 该注解继承自 @Configuration,两者功能一致,标注当前类是一个配置类。
注解源码如下:

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

其下可以通过@Bean标注将方法返回的类对象依赖注入到Spring容器中。

需要注意的是,虽然@Configuration继承自@Component,但@Configuration采用CGLIB的动态代理功能,使 @Bean注释的方法都会被动态代理,调用时通过BeanFactory返回相同的对象。 @Configuration注解是单例模式,@Component注解是多例模式。

(2)@EnableAutoConfiguration :spring的自动装配注解,该注解会根据项目添加的jar包依赖项,完成对项目依赖的自动装配。
注解源码如下:

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

@EnableAutoConfiguration注解默认会扫描 spring-boot-autoconfigure:xxx.RELEASE.jar包下META-INF/spring.factories文件中,所有org.springframework.boot.autoconfigure.EnableAutoConfiguration值中对应的*Configuration类,并根据类上的条件注解判定结果,将符合条件的配置类加载到spring容器中。·
代码片段如下:

……
# 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,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
……

注意:如果项目要剔除某个依赖的自动装配,可以通过本注解的exclude 属性,设置要剔除的配置类即可。(使用上面auto Configure 中的类命名), 示例如下:

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) // -> 禁止数据源自动装配

启动spring时,若开启DEBUG模式,可以在启动日志的CONDITIONS EVALUATION REPORT中查看到项目模块的装配情况
自动装配日志内容截图
注意:
1、@EnableAutoConfiguration通过资源导入注解(@Import(AutoConfigurationImportSelector.class)),将``类引入到启动类中

2、配置类加载规则,通过扫描SpringBoot自动配置包内spring-boot-autoconfigure-*.RELEASE.jar/META-INF/spring.factories文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration属性所配置的所有*AutoConfiguration类,进行装载。在扫描到*AutoConfiguration类时,所有类中的@ConditionalOn*注解生效,判断其所需的类是否存在(或生效),以决定是否装载对应配置。

参考资料:
https://www.cnblogs.com/leihuazhe/p/7743479.html
https://blog.csdn.net/mapleleafforest/article/details/87273213

(3)@ComponentScan : 配置组件自动扫描的指令,以便提供与XML配置<context:component-scan base-package="org.example"/> 相同的功能,继承于@ComponentScans注解。

注解源码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;String resourcePattern() default    ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;boolean useDefaultFilters() default true;Filter[] includeFilters() default {};Filter[] excludeFilters() default {};boolean lazyInit() default false;@Retention(RetentionPolicy.RUNTIME)@Target({})@interface Filter {FilterType type() default FilterType.ANNOTATION;@AliasFor("classes")Class<?>[] value() default {};@AliasFor("value")Class<?>[] classes() default {};String[] pattern() default {};}
}

从注解源码中,可以看到@ComponentScan注解的一些重要属性

  • value()basePackages
    属性 互为别名,用于指定@ComponentScan注解扫描的包路径,若不设置则默认从@ComponentScan注释的类开始向下扫描。
  • boolean useDefaultFilters() default true;
    属性 标记是否启用默认过滤规则,该规则用于扫描@Component,@Repository,@Service,@Controller 注解注释的类。
  • includeFilters 属性指定特定扫描规则,通常此时关闭默认扫描规则。
  • excludeFilters 属性用于排除特定扫描规则。
  • @Filter 内部注解可以配合 excludeFiltersincludeFilters 实现 排除 或 增加 某个过滤规则

1、@ComponentScan 常用应用示例:

  1. @ComponentScan(“org.items.tysite”)
    扫描 [org.items.tysite] 包下的所有默认注解,如@Controller、@Service、@Component等
  2. @ComponentScan(basePackageClasses = ThymeleofController.class, useDefaultFilters = false)
    扫描 指定的 ThymeleofController 类
  3. @ComponentScan(value = “org.items.tysite”, includeFilters = { @Filter(type = FilterType.ANNOTATION, value = Component.class) }, useDefaultFilters = false)
    只扫描 [org.items.tysite] 包下,由 @Component注解注释的类
  4. @ComponentScan(value = “org.items.tysite”, excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Component.class) })
    扫描 [org.items.tysite] 包下,除@Component注解之外的所有默认规则注解
  5. @ComponentScan(value = “org.items.tysite”, includeFilters = { @Filter(type = FilterType.CUSTOM, value = CustomTypeFilter.class) }, useDefaultFilters = false)
    扫描 [org.items.tysite] 包下,基于CustomTypeFilter 自定义规则加载Bean

2、自定义策略使用案例
以上面示例5的配置作为配置样例,通过实现TypeFilter接口,创建自定义的策略,并通过@Configuration 配置 @ComponentScan

@Configuration
@ComponentScan(value = "org.items.tysite", includeFilters = { @Filter(type = FilterType.CUSTOM, value = CustomTypeFilter.class) }, useDefaultFilters = false)
public class CustomComponentScanConfiguration { }
public class CustomTypeFilter implements TypeFilter {@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {ClassMetadata classMetadata = metadataReader.getClassMetadata();String className = classMetadata.getClassName();if (CommonConsts.class.getName().equals(className)) {System.out.println("成功加载类 ["+CommonConsts.class.getName()+"]");return true;} else {return false;}}
}

注意: 项目使用 @SpringBootApplication 的注解扫描时,以上示例无法生效。因为 @SpringBootApplication注解中排除了 FilterType.CUSTOM 自定义的扫描规则 (详见注解源码)。如果我们的项目中需要使某个类或注解注释不被注入时,可以通过继承TypeExcludeFilter类并重写match方法实现。

match 方法的 MetadataReader 参数,可以获取到扫描对象 类信息、注解信息、以及资源信息,可以根据以上信息判断要注入的类

  //获取扫描到的类注解信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//获取扫描到的类信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//获取扫描到的类资源信息Resource resource = metadataReader.getResource();

参考资料:
https://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/core.html#beans-scanning-autodetection

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/TypeExcludeFilter.html#match-org.springframework.core.type.classreading.MetadataReader-org.springframework.core.type.classreading.MetadataReaderFactory-

https://blog.csdn.net/luojinbai/article/details/85877956

这篇关于第三章 springboot -- 第一节 SpringBoot启动注解 ( @SpringBootApplication )的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/951280

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2