一、Spring
1、优点
Spring框架是Java应用程序开发中的一套全面基础架构的提供者,包含很多功能和一些开箱即用的模块如:Spring JDBC、Spring MVC、SpringSecurity、SpringAOP、SpringORM、SpringTest等,这些模块相当于一系列封装好的功能,开发的时候只需要引入相应的包就可以直接使用,大大减少了开发的时间,提高开发的效率
2、劣势
spring的代码组件是轻量级的,但是配置却是重量级的,配置都代表了开发时的损耗;
依赖管理也是耗时耗力的,需要分析要导入哪些库,选错了版本会造成不兼容问题
二、Spring Boot框架
1、简介
SpringBoot是一个构建在Spring框架顶部的项目。它提供了一种更简单、更快捷的方法来设置、配置和运行简单的基于web 的应用程序。
在过去Spring框架中,我们需要为应用配置所有的内容,会有很多的配置文件,在springboot中我们使用@注解进行配置,springboot能根据我们选择的以来配置,来启动我们需要的功能
2、 核心功能
2.1 起步依赖
本质上是一个Maven项目对象模型(Project Object Model,POM ),将具备某种功能的的坐标打包到一起,并且提供一些默认的功能
2.2 自动配置
是一个应用程序启动时的过程,由spring自动完成
3、组件
- SpringBoot 自动配置:spring boot启动时能够检测某些框架的可用性,检测到框架就会自动配置
- Spring Boot Core:其他Spring模型的基础
- Spring Boot Starters:帮助项目启动,自动添加启动项目和依赖性
4、特点
4.1 实现微服务
微服务是一种细小的粒度,可直接通过端口对外提供服务,spring boot提供REST风格API暴露微服务,与客户端交互采取JSON数据格式
4.2 自动配置
根据依赖关系自动配置应用程序
在pom.xml中添加一个依赖就等于加入了对应的组件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
说明这个应用启动了spring-boot-starter-web 这个功能,也就是能提供REST端点暴露,让客户端 通过/xxx/xx这样形式URL访问内部服务和资源。
创建一个SpringBootde 应用,只需要在应用入口类上标注@SpringBootApplication
@SpringBootApplication = @EnableAutoConfiguration + @Configuration + @ComponentScan.
@EnableAutoConfiguration: Spring Boot会根据添加的maven的pom.xml的依赖项自动配置加载 相应的依赖组件,它能智能感知上下文。
@Configuration表示当前类是一个配置工厂,可生产当前项目所需的各种Bean实例,类似于XML 中的。如果你想为当前项目导入其他组件,除了配置pom.xml以外,还可以在这里用代码使用工 厂模式创建,类的方法上使用@Bean标注,也可用函数式方式创建,性能更好。
@ComponentScan是用于自动扫描包,如果不明确声明,只使用@SpringBootApplication,那么 就扫描当前所在的包和子包。
4.3 自定义配置
在application.properties 文件中配置JPA的配置
spring.datasource.url=jdbc:mysql://localhost:3306/temp
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=update
4.4 模块化
一般情况下,一个SpringBoot应用 = 一个微服务 = 一个模块 = 一个有边界的上下文,如果有多个模 块,我们就开发多个微服务,多个SpringBoot应用,然后使用Springcloud实现它们之间动态访问和监 控。 但是有时我们也会希望将多个模块放入一个SpringBoot应用中,这样模块之间调用可以在一个JVM 内进行,适合小型系统的部署,随着规模扩大,我们还可将这些模块变成一个个微服务,以SpringBoot 应用分布式运行。
4.5 独立打包
一个Spring Boot项目可以直接打包成为jar包,然后通过Java -jar 命令启动该应用程序,而不像其它应 用程序一样打包为war包部署到服务器上才能启动使用。
4.6 内嵌服务器
SpringBoot内嵌服务器默认是tomcat,还有Jetty等其他服务器可以选择,tomcat配置不像过去那样我 们可以直接配置,需要通过SpringBoot去配置和调度。过去的模式是:先启动服务器,再启动war应用,服务就启动了;现在的模式是直接启动服务就可以使用了。一个tomcat服务器=一个微服务。
三、开始一个SpringBoot 应用
1、 https://start.spring.io/
解压缩后导入IDE 项目目录如下
2、IDEA新建项目
1、File->New Project,选择 Spring Initializr,选择JDK,点击 Next
next 一直到finish,项目结构如下
起步依赖
<-- 起步依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<-- SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
引导类
启动
四、原理分析
1 起步依赖
1.1 spring-boot-starter-parent
在这里面会定义了版本,依赖管理,插件管理
1.2 spring-boot-starter-web
将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。
2 自动配置
启动类的 @SpringBootApplication
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.boot.autoconfigure;
@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 {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@SpringBootConfiguration:等同与@Configuration,既标注该类是Spring的一个配置类
@EnableAutoConfiguration:SpringBoot自动配置功能开
package org.springframework.boot.autoconfigure;
@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 {};
}
@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类
@AutoConfigurationPackage中有从META-INF/spring.factories文件中读取指定类对应的类名称列表
spring.factories有很多有关自动配置的配置信息
springApplication在获取这些类名后再加载
五、配置文件
spring boot是基于约定的,很多配置都是由默认值,可以通过修改配置文件来替换默认配置,配置文件通常为application.properties或者application.yml(application.yaml)
springboot 会默认从Resource目录下加载application.properties或者application.yml(application.yaml)
语法
application.properties文件是键值对类型的文件
yml文件:是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入
文档URL:官方文档
常用如下
# QUARTZ SCHEDULER (QuartzProperties)
spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.quartz.job-store-type=memory # Quartz job store type.
spring.quartz.properties.*= # Additional Quartz Scheduler properties.
# ----------------------------------------
# WEB PROPERTIES
# ----------------------------------------
# EMBEDDED SERVER CONFIGURATION (ServerProperties)
server.port=8080 # Server HTTP port.
server.servlet.context-path= # Context path of the application.
server.servlet.path=/ # Path of the main dispatcher servlet.
# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
# JACKSON (JacksonProperties)
spring.jackson.date-format= # Date format string or a fully-qualified date format class name. For instance, `yyyy-MM-dd HH:mm:ss`.
# SPRING MVC (WebMvcProperties)
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the dispatcher servlet.
spring.mvc.static-path-pattern=/** # Path pattern used for static resources.
spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.
spring.datasource.password= # Login password of the database.
# JEST (Elasticsearch HTTP client) (JestProperties)
spring.elasticsearch.jest.password= # Login password.
spring.elasticsearch.jest.proxy.host= # Proxy host the HTTP client should use.
spring.elasticsearch.jest.proxy.port= # Proxy port the HTTP client should use.
spring.elasticsearch.jest.read-timeout=3s # Read timeout.
spring.elasticsearch.jest.uris=http://localhost:9200 # Comma-separated list of the Elasticsearch instances to use.
spring.elasticsearch.jest.username= # Login username.
用@Value 注解在代码中可以获得配置文件的值
person:
name: zhangsan
age: 18
@RestController
public class StartController {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@RequestMapping("toStart")
public String toStart() {
return "访问成功";
}
}
使用@ConfigurationProperties注解可以将配置文件中的配置自动与实体进行映射
@RestController
@ConfigurationProperties(prefix = "person")
public class StartController {
private String name;
private Integer age;
@RequestMapping("toStart")
@ResponseBody
public String toStart() {
return "访问成功";
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}