Spring Boot————简介与Spring时代的承接

引言

最近,公司正在开发一个景区系统的项目,涉及到Spring Boot框架的使用,在此记录下Spring Boot框架应该知道的基础知识。

一、产生

SpringBoot是顺应现在微服务(MicroServices)理念而产生的一个微框架(同类还有Dropwizard),用来构建基于Spring框架的标准化的独立部署应用程序。

二、SpringBoot快速开始:

我们使用Maven构建项目,所以新建一个maven项目, pom.xml中添加如下两个关键因素:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
</parent>
...
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

使用spring-boot-starter-parent作为当前项目的parent可以享受到spring boot应用相关的一系列依赖(dependency), 插件(plugins)等装备, 而添加spring-boot-starter-web这个依赖,则纯粹是我们希望构建一个独立运行的web应用而已(注意, 没有version元素定义,因为spring-boot-starter-parent已经提供了相应的dependencyManagement)。有了以上配置,我们就可以按照SpringMVC的套路添加相应的Controller实现就可以了。

要让Spring Boot可以独立运行和部署,我们需要一个Main方法入口。

三、Spring Boot如何工作

3.1 Spring 特性回顾

3.1.1 XML配置与JavaConfig的选择问题

SpringBoot倡导基于JavaConfig的形式来“装配”应用, 但有些层面,我们还是希望根据公司的生态圈和基础设施现状,对其进行一些定制,以便更好的融入并享受一系列生态,而大部分要集成外部已有系统的时候, 通过xml集中明确化配置我认为是比较合适的做法。

总之, 这两种方式不应该是东风压倒西风,而应该根据情况来选择。 从我的角度来讲,我希望在SpringBoot里,除了Main入口类和autoscan相关的地方使用JavaConfig, 其它最好以xml配置。

3.1.2 @Configuration注解

@Configuration这个注解就是JavaConfig的典型代表。标注了这个注解的Java类定义,会以Java代码的形式(对应于xml定义的形式)提供一系列的bean定义和实例。 结合AnnotationConfigApplicationContext自动扫描的功能,就可以构建一个基于Spring容器的Java应用。

一系列标注了@Configuration的Java类的集合,对应于“昨日”的一系列xml配置文件。

3.1.3 @ComponentScan注解

@ComponentScan对应xml时代的<context:component-scan>。用来扫描classpath下标注了相应注解的Bean定义,然后加载到Spring容器中。

一般配合@Configuration注解来使用,你可以将@Configuraiton做的事情是纯手工定义bean然后添加到Spring容器, 而@ComponentScan则是自动收集bean定义并添加到Spring容器。

3.1.4 @Import注解

Spring容器的配置可以分散在多个物理存在的配置类或者配置文件中。

@Import允许将其它JavaConfig形式的配置类引入到当前的@Configuration标注的配置类当中, 对应于原来xml时代的<import/>, 甚至于也可以通过@ImportResource将xml形式定义的配置也引入当前JavaConfig形式的配置类当中。

3.1.5 @PropertySource注解

配合@Configuration使用, 用来加载.properties内容到Environment,比如:@PropertySource("classpath:/application.properties"),并需要容器中配置一个PropertySourcesPlaceholderConfigurer。

@PropertySource和@PropertySources的区别在于, 后者属于前者的Aggregation类型, 在有多个.properties资源需要引入的情况下,如果能够使用Java8的repeatable annotation特性,则只需要声明多个@PropertySource就行了, 否则,作为fallback方案,使用@PropertySources然后再其中引用多个@PropertySource好了。

3.1.6 Environment和Profile

这两个概念应该是Spring3时代引入的, Environment用来统一表达当前应用程序运行环境的概念,会以Properties的形式提供一系列该环境下的上下文信息,而且允许当前应用程序获取activeProfile是哪个。
说实话,Environment的设计,我觉得到提供上下文信息这一关键职能就可以了, 而Profile的设计,则有些太过于Monolithic时代的做事风格。 Profile一般用来提供某些灵活性, 但这种灵活性是内部化的, 这意味着, 你的软件实体需要知道外面可能提供多少种profiles, 然后在不同的profile下,我的软件实体需要做什么样的调整。 而实际上, 软件实体从研发到交付和使用, 最好是在整条流水线上设计和生产都是一致, 只有“销售”之前,才根据目标环境或者目标客户调整“包装”和配置, 然后“发货”, 用户拿到手的产品(当然包括我们搞的软件产品)应该是开箱即用的, 这个产品既不会存在我不需要的功能,也不应该每次使用的时候先自己“很智能”的扫描一下上下文环境然后决定使用哪一个Profile。尤其是在微服务时代,随着你服务数量的增长, 服务数量 * Environment数量 * 所谓的Profile数量更是指数级增长 3, 如果应用开发的时候还要考虑这么多,那出问题的几率就更大了。
所以, 在Microservices时代,我们更建议外部化你的软件产品差异化配置管理, 尽量减少Profile的滥用甚至不用(这就减少一个纬度的管理)。

3.2 对@EnableAutoConfiguration的理解

在本文之前提到的所有Annotation都属于SpringFramework提供的, 现在要说的这个Annotation,即@EnableAutoConfiguration, 则属于SpringBoot。
@EnableAutoConfiguration的定义信息如下:

@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Inherited
@Import(value={org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.class,org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar.class})
public @interface EnableAutoConfiguration

标注了这个Annotation的配置类将触发一系列动作, 也是SpringBoot“黑魔法”的核心, 魔法大体上是这样发生的: SpringBoot一旦发现@EnableAutoConfiguration, 那么就使用Spring框架提供的SpringFactoriesLoader这个特性去扫描当前应用classpath下所有META-INF/spring.factories元信息配置, 然后根据当前使用场景需要, 加载符合当前场景需要的配置类型并供当前或者后继流程使用, 对于@EnableAutoConfiguration的场景,就是提取以org.springframework.boot.autoconfigure.EnableAutoConfiguration作为key标志的一系列Java配置类,然后将这些Java配置类中的bean定义加载或者说灌入Spring容器中。
当然, EnableAutoConfiguration通过SpringFactoriesLoader筛选并加载进来的这些Java配置类里面,我们其实还可以进一步对要加载到容器的bean定义进行筛选, 这就会用Spring3系列引入的@Conditional“军团”, 通过像@ConditionalOnClass, @ConditionalOnMissingBean等具体的类型和条件来进一步决定加载还是不加载哪些bean定义。

3.3 Enter Main

有了上面的这些“前戏”, 下面我们正式进入正题了...
每一个SpringBoot应用都有一个入口类,在其中定义main方法, 然后使用SpringApplication这个类来加载指定配置并运行SpringBoot应用程序, 在很多SpringBoot的介绍中,都会使用当前入口类既作为配置(标注@Configuration)又作为入口类, 比如我们的HellSpringBoot:

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

@SpringBootApplication等效于@Configuraiton + @EnableAutoConfiguration + @ComponentScan, 所以, 当我们将HelloSpringBoot.class作为JavaConfig配置类传入SpringApplication.run方法之后, SpringApplication.run方法就知道从哪里加载并扫描必要的bean定义了。
现在,剩下的就是要搞清楚SpringApplication.run里面发生了什么。

鸣谢

Spring Boot Rock’n’Roll

Spring Boot 基础教程(基于1.3.x-1.5.x) 快速入门 chapter1:基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API 使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程 工程配置 chapter2-1-1:配置文件详解:自定义属性、随机数、多环境配置等 chapter2-1-2:2.0 新特性(一):配置绑定全解析 chapter2-2-1:2.0 新特性(二):新增事件ApplicationStartedEvent Web开发 chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试 chapter3-1-2:使用Thymeleaf模板引擎渲染web视图 chapter3-1-3:使用Freemarker模板引擎渲染web视图 chapter3-1-4:使用Velocity模板引擎渲染web视图 chapter3-1-5:使用Swagger2构建RESTful API chapter3-1-6:统一异常处理 chapter3-1-7:使用Java 8中LocalDate等时间日期类的问题解决 chapter3-1-8:扩展XML请求和响应的支持 数据访问 chapter3-2-1:使用JdbcTemplate chapter3-2-2:使用Spring-data-jpa简化数据访问层(推荐) chapter3-2-3:多数据源配置(一):JdbcTemplate chapter3-2-4:多数据源配置(二):Spring-data-jpa chapter3-2-5:使用NoSQL数据库(一):Redis chapter3-2-6:使用NoSQL数据库(二):MongoDB chapter3-2-7:整合MyBatis chapter3-2-8:MyBatis注解配置详解 chapter3-2-9:使用Flyway来管理数据库版本 chapter3-2-10:使用LDAP来统一管理用户信息 chapter3-2-11:Spring Boot中增强对MongoDB的配置(连接池等) 事务管理 chapter3-3-1:使用事务管理 chapter3-3-2:[分布式事务(未完成)] 其他内容 chapter4-1-1:使用@Scheduled创建定时任务 chapter4-1-2:使用@Async实现异步调用 chapter4-1-3:使用@Async实现异步调用:自定义线程池 chapter4-1-4:使用@Async实现异步调用:资源优雅关闭 chapter4-1-5:使用@Async实现异步调用:使用Future以及定义超时 日志管理 chapter4-2-1:默认日志的配置 chapter4-2-2:使用log4j记录日志 chapter4-2-3:对log4j进行多环境不同日志级别的控制 chapter4-2-4:使用AOP统一处理Web请求日志 chapter4-2-5:使用log4j记录日志到MongoDB chapter4-2-6:Spring Boot 1.5.x新特性:动态修改日志级别] 安全管理 chapter4-3-1:使用Spring Security chapter4-3-2:[使用Spring Session(未完成)] 缓存支持 chapter4-4-1:注解配置与EhCache使用 chapter4-4-2:使用Redis做集中式缓存 邮件发送 chapter4-5-1:实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件 消息服务 chapter5-1-1:[JMS(未完成)] chapter5-2-1:Spring Boot中使用RabbitMQ 其他功能 chapter6-1-1:使用Spring StateMachine框架实现状态机 Spring Boot Actuator监控端点小结 在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo进行服务治理 chapter9-2-2:Spring Boot与Dubbo中管理服务依赖
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值