在开始了解Spring Boot之前,我们需要先了解一下Spring,因为Spring Boot的诞生和Spring是息息相关的,Spring Boot是Spring发展到一定程度的一个产物,但并不是Spring的替代品,Spring Boot是为了让程序员更好的使用Spring。说到这里可能有些人会迷糊,那到底Spring和Spring Boot有着什么样的联系呢?
在开始之前我们先了解一下Spring,Spring的前身是interface21,这个框架最初是为了解决EJB开发笨重臃肿的问题,为J2EE提供了另一种简单又实用的解决方案,并在2004年3月发布了Spring 1.0正式版之后,就引起了Java界广泛的关注和热评,从此Spring在Java界势如破竹迅速走红,一路成为Java界一颗璀璨夺目的明星,至今无可替代,也一度成为J2EE开发中真正意义上的标准了,而他的创始人Rod Johnson也在之后声名大噪,名利双收,现在是一名优秀的天使投资人,走上了人生的巅峰。
那既然Spring已经这么优秀了,为什么还有了之后Spring Boot?
因为随着Spring发展的越来越火,Spring也慢慢从一个小而精的框架变成了,一个覆盖面广大而全的框架,另一方面随着新技术的发展,比如nodejs、golang、Ruby的兴起,让Spring逐渐看着笨重起来,大量繁琐的XML配置和第三方整合配置,让Spring使用者痛苦不已,这个时候急需一个解决方案,来解决这些问题。
就在这个节骨眼上Spring Boot应运而生,2013年Spring Boot开始研发,2014年4月Spring Boot 1.0正式发布,Spring Boot诞生之初就受到业界的广泛关注,很多个人和企业陆续开始尝试,随着Spring Boot 2.0的发布,又一次把Spring Boot推向了公众的视野,也有越来越多了的中大型企业把Spring Boot使用到正式的生产环境了。值得一提的是Spring官方也把Spring Boot作为首要的推广项目,放到了官网的首位。
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。Spring Boot其实就是一个整合很多可插拔的组件(框架),内嵌了使用工具(比如内嵌了Tomcat、Jetty等),方便开发人员快速搭建和开发的一个框架。
比如我们要创建一个web项目,通常需要添加多个依赖,而SpringBoot则会帮助开发着快速启动一个web容器,我们只需要在pom文件中添加如下一个starter-web依赖即可。SpringBoot大大简化了我们的编码,我们不用一个个导入依赖,直接一个依赖即可。
Spring由于其繁琐的配置,一度被人认为“配置地狱”,各种XML、Annotation配置,让人眼花缭乱,而且如果出错了也很难找出原因。Spring Boot更多的是采用Java Config的方式,对Spring进行配置。
一键启动,解压jar,运行jar;
不需要预部署到应用服务器;
降低对运行环境的基本要求,环境变量中有JDK即可;
采用了spring-boot-start-actuator之后,直接以REST的方式,获取进程的运行期性能参数。
快速构建项目。
对主流开发框架的无配置集成。
项目可独立运行,无须外部依赖Servlet容器。
提供运行时的应用监控。
极大地提高了开发、部署效率。
按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,xml配置如
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.0.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.7.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作
按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
注解@SpringBootApplication的源码
@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 {
}
可以把@SpringBootApplication看作是
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
这个三个注解的集合,而其中这三个注解的作用分别是:
允许在上下文中注册额外的bean或者导入其他配置项
启动SpringBooot的自动配置机制
扫描被@Compent(@Service@Controller)注解的bean,注解是会默认扫描启动类所在的包下的所有的类,也可以自定义不扫描一些bean
接下来去看这个代码@EnableAutoConfiguration
@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.autoconfigure.AutoConfigurationPackage
@org.springframework.context.annotation.Import({org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
java.lang.String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
java.lang.Class<?>[] exclude() default {};
java.lang.String[] excludeName() default {};
}
会发现它只是一个简单的注解,自动装配核心功能的实现实际上是通过AutoConfigurationImportSelector来实现的,所以再看一下这个类AutoConfigurationImportSelector
public class AutoConfigurationImportSelector implements org.springframework.context.annotation.DeferredImportSelector, org.springframework.beans.factory.BeanClassLoaderAware, org.springframework.context.ResourceLoaderAware, org.springframework.beans.factory.BeanFactoryAware, org.springframework.context.EnvironmentAware, org.springframework.core.Ordered {
}
public interface DeferredImportSelector extends org.springframework.context.annotation.ImportSelector {
}
public interface ImportSelector {
java.lang.String[] selectImports(org.springframework.core.type.AnnotationMetadata annotationMetadata);
@org.springframework.lang.Nullable
default java.util.function.Predicate<java.lang.String> getExclusionFilter() { /* compiled code */ }
}
锁定到了最后一个,也就是说AutoConfigurationImportSelector类是实现了ImportSelector接口,也实现了接口中的selectImports方法,这个方法的作用就是:获取所有的符合条件的全限定类名,这些类需要被加载到IOC容器当中。
总的来说就是
Spring Boot 通过@EnableAutoConfiguration开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖
@ComponentScan:组件扫描配置 约定 当前所在的包及子包下的都会被扫描到
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。