一、引言
不知道大家有没有想过这样一个问题,关于我们的 Spring Boot 啊,前面很多地方我都是说 Spring 帮我们做的,那他到底是怎么帮我们做的呢?就比如我们的启动类,叫什么 XXXX Application
,那大家有没有想过,为什么这个启动类就能启动我们整个程序呢?那我们换一个名字可不可以?就一定要叫 某某某Application 吗?带着这些疑问,深入的走进我的这篇博文吧。
二、Spring 加载 Bean
不知道各位程序猿有没有想过,Spring 是如何加载 Bean 的呢?比如说我们设置 Bean 类型的时候,就只需要声明注解就行了,Spring 就能帮助我们这个类,那 Spring 究竟是如何管理、如何添加到 Spring 里面的呢?其实这些工作在我们启动程序的时候就已经做好了,想要知道怎么做的,那我们就要先弄明白启动类 -> XXXX Application
是怎么回事,我们可以改一下启动类的路径,如下:
正常来说,我们只需要访问 "127.0.0.1:8080/blog/b1" 这个地址的话就可以看到 "b1 test" 这段信息了,但是通过我们的访问发现,页面出现了这种情况:
它报了一个 404 的错,但是我们检查发现,我们的 url 并没有出现问题,这就是我们的启动类没有扫描到这个 Bean 出现的问题了,我们可以点进 @SpringBootApplication
这个注解去看看到底怎么回事,如下:
2.1、元注解
@Target({ElementType.TYPE})
- 作用:
@Target
注解用于指定被注解的注解可以应用的Java元素类型。换句话说,它限制了你的注解可以放在哪里。 - 参数:
ElementType
是一个枚举类型,包含了许多表示Java元素的常量,如TYPE
、METHOD
、FIELD
等。在这个例子中,{ElementType.TYPE}
表示注解只能被用于类、接口(包括注解类型)或枚举声明上。 - 示例:如果你有一个注解被
@Target({ElementType.TYPE})
修饰,那么它就不能被用于方法或字段上,只能被用于类、接口或枚举上。
@Retention(RetentionPolicy.RUNTIME)
- 作用:如上所述,
@Retention
注解用于指定被注解的注解的保留策略。 - 参数:
RetentionPolicy.RUNTIME
表示注解在运行时可通过反射机制读取。这是最常见的保留策略之一,因为它允许程序在运行时查询注解信息。 - 示例:如果你的注解需要被反射API在运行时访问,你应该使用
@Retention(RetentionPolicy.RUNTIME)
。
@Documented
- 作用:如上所述,
@Documented
注解指示被注解的注解应该被 javadoc 或类似的工具文档化。 - 参数:
@Documented
注解没有参数。 - 示例:如果你的注解包含了一些重要的信息,并且你希望这些信息能够出现在使用了你注解的元素的文档中,那么你应该使用
@Documented
。
@Inherited
- 作用:
@Inherited
注解表示被注解的注解将具有继承性。如果某个类使用了某个带有@Inherited
注解的注解,那么这个类的子类也将自动继承该注解,而无需显式声明。 - 参数:
@Inherited
注解没有参数。 - 示例:假设你有一个注解
@MyInheritedAnnotation
被@Inherited
修饰,并且它被用在了类BaseClass
上。那么,任何继承自BaseClass
的子类都将自动继承@MyInheritedAnnotation
注解,即使这些子类没有显式地使用这个注解。
大家不用太深究这些元注解,知道个大概就行,主要看下面的那三个注解。
2.2、其他注解
首先就是上面说的启动类那个,@ComponentScan
这个注解就是标识是扫描路径的,可以通过 basePackageClasses 或 basePackages 来定义要扫描的特定包, 如果没有定义特定的包,将从声明该注解的类的包开始扫描,这也是为什么 Spring Boot 项目声明的注解类必须要在启动类的目录下。如何定义呢?如下:
@SpringBootApplication
@ComponentScan("com.zmbdp.blogtest")// 自定义扫描路径,全限定名称
public class BlogTestApplication {
public static void main(String[] args) {
SpringApplication.run(BlogTestApplication.class, args);
}
}
这样设置之后就可以扫描到了,结果如下:
然后就是我们的 @SpringBootConfiguration
注解了,其实这个注解点进去之后会发现,是这样的:,里面有个 @Configuration
注解,说明这标识着就是一个 @Configuration
类,只不过给 Spring 包装了一下,增加了一些功能(了解即可)。
2.3、@EnableAutoConfiguration
注解
接下来就是比较重要的 @EnableAutoConfiguration
注解了,这是一个通过检查类路径中的依赖和配置来自动配置 Spring 应用程序,然后就会看你设置的 application.properties
或 application.yml
,导入两个地方的,一个地方是 META-INF/spring.factories
配置文件。这个配置文件包含了 Spring Boot 自动配置类的列表,这些类根据项目的依赖和配置自动注册到 Spring 容器中。还有一个地方是 org.springframework.boot.autoconfigure.AutoConfiguration.imports
这个文件是加载其他你需要的一些依赖,如下:
还是有些能看明白的,比如说 data 啊,cache(验证码),aop 这些。
讲到这里,这个 Spring 的启动类的自动配置这块算是差不多弄明白了。
三、总结
通过这篇文章,我们深入探讨了 Spring Boot 启动类的奥秘,了解了 Spring 是如何通过一系列注解和自动配置机制来加载和管理 Bean 的。在这其中,@SpringBootApplication、@ComponentScan、@EnableAutoConfiguration 等注解起到了至关重要的作用,它们帮助我们简化了配置过程,让我们能够更加专注于业务逻辑的开发。通过理解这些背后的原理,不仅能帮助我们更好地掌握 Spring Boot 的核心机制,还能在实际开发中更加灵活地运用这些工具,提升开发效率。
四、结语
Spring Boot 不仅仅是简化开发的工具,更是我们深入掌握技术、提升编程思维的伙伴。通过探究它的启动原理,我们不仅解开了神秘的面纱,也收获了驾驭复杂系统的信心。未来的开发道路上,希望大家能带着好奇心与探索精神,不断突破自我边界,拥抱未知的挑战。技术的世界广阔而深邃,只有不断求知和钻研,才能在这片领域中留下属于自己的印记。