SpringBoot

114 阅读4分钟

SpringBoot

spring缺点

Spring特性配置繁琐

项目的依赖管理不兼容

springboot特点:

基于约定优于配置

springboot核心功能:

1 起步依赖 Starter

本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。 简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。

原先需要导入很多坐标。现在打包所有坐标。

2 自动配置

一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定 Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。

配置sessionFactory需要DataSource,spring需要注入。

springboot会自动把数据源注入。

SpringBoot入门

1 创建Maven工程

SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent

所有的springboot工程都必须继承springbootstater

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>

SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动

以功能单位 springboot自动导入

<dependencies>
<!--        web功能的起步依赖 内部集成spring-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

整合spring和springmvc

Tomcat started on port(s): 8080 (http) with context path '' 当前tomcat启动,当前名称是空的,内嵌tomcat 没有内嵌tomcat。

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Aug 11 09:11:55 CST 2020 There was an unexpected error (type=Not Found, status=404). No message available

web tomcat有默认的内嵌界面

2 编写SpringBoot引导类

@SpringBootApplication // springboot引导类
public class SpringBootApp {
// main是java程序入口
public static void main(String[] args) {

    SpringApplication.run(SpringBootApp.class);
}
}

3 编写控制器

@Controller
public class QuickController {

@RequestMapping("/quick")
@ResponseBody
public String quick() {
    return "Hello";
}
}

SpringBoot入门解析

声明该类是一个springboot的引导类 @SpringBootApplication:标注SpringBoot的启动类,该注解具备多种功能

SpringApplication.run(SpringBootApp.class) 代表运行SpringBoot的启动类,参数为SpringBoot 启动类的字节码对象

SpringBoot工程热部署

我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大 量的时间,我们可以在修改代码后不重启就能生效,在 pom.xml 中添加如下配置就可以实现这样的功能,我们称 之为热部署。

IDEA进行SpringBoot热部署失败原因

1 出现这种情况,并不是热部署配置问题,其根本原因是因为Intellij IEDA默认情况下不会自动编译,需要对IDEA进 行自动编译的设置

2 Shift+Ctrl+Alt+/,选择Registry running

SpringBoot工程热部署

Spring Initializr

SpringBoot原理分析

起步依赖(坐标打包)

spring-boot-starter-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

		<resource>
            <filtering>true</filtering>
            <directory>${basedir}/src/main/resources</directory>
            <includes>
                <include>**/application*.yml</include>
                <include>**/application*.yaml</include>
                <include>**/application*.properties</include>
            </includes>
        </resource>

pom.xml中的spring-boot-starter-dependencies MAVEN版本控制

<properties>    
<activemq.version>5.15.3</activemq.version>    <antlr2.version>2.7.7</antlr2.version>    
<appengine-sdk.version>1.9.63</appengine-sdk.version>    <artemis.version>2.4.0</artemis.version>

<dependencyManagement>

一部分坐标的版本、依赖管理、插件管 理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以 起步依赖的作用就是进行依赖的传递

spring-boot-starter-web

spring-boot-starter-json 引入jackson-databind

spring-boot-starter-tomcat

spring-web

spring-webmvc

spring-boot-starter-web就是将web开发要使用的 spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的 坐标就可以进行web开发了,同样体现了依赖传递的作用。

自动配置

@SpringBootApplication

约定当前包和子包所有的都扫描(同级和子包都扫描)

@SpringBootConfiguration <> @Configuration spring配置类

@EnableAutoConfiguration 自动配置核心注解

@Import({AutoConfigurationImportSelector.class})

导入选择器

List configurations = this.getCandidateConfigurations(annotationMetadata, attributes); 加载某些配置

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\

@EnableConfigurationProperties({ServerProperties.class})

ServerProperties类

@ConfigurationProperties(
prefix = "server",
ignoreUnknownFields = true
)

spring默认启动tomcat

{
  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
  "defaultValue": 8080,
  "name": "server.port",
  "description": "Server HTTP port.",
  "type": "java.lang.Integer"
},

@ComponentScan 扫描

application.properties

当前tomcat启动服务器端口号

server.port=8088

当前web应用名称

server.servlet.context-path=/haha

SpringBoot的配置文件

SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用 application.properties或者application.yml(application.yaml)进行配置。

SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件

application.yml配置文件

语法

普通数据 value之前有一个空格 name: hello

对象配置 value之前有一个空格

persion: name: hello age: 22 add: rrrr

端口号 server: port: 8088

行内对象配置 persion: {name: hello, age: 22, add: rrr}

配置集合和数组(普通字符串) 配置集合 -空格 city:

  • beijing
  • tianjin
  • ee

city: [beijing,tianjin,ee]

配置集合和数组(对象) persion:

  • name: hello age: 22 add: rrrr
  • name: hello1 age: 22 add: rrrrtttt

persion: [{name: hello, age: 22, add: rrr},{name: hello1, age: 22, add: rrrrtttt}]

配置文件与配置类的属性映射方式

1 @Value 精确匹配 单一获取比较繁琐

@Value("${person.name}")

@Controller public class QuickController2 {

@Value("${name}")
private String name;

@RequestMapping("/quick2")
@ResponseBody
public String quick2() {
    return "haha 1Hello"+name;
}
}

2 @ConfigurationProperties(prefix="配置文件中的key的前缀") 自动匹配

@Controller
@ConfigurationProperties(prefix = "persion")
public class QuickController3 {

private String name;

@RequestMapping("/quick3")
@ResponseBody
public String quick3() {
    return "haha 1Hello"+name;
}

public void setName(String name) {
    this.name = name;
}
}

<!--        @ConfigurationProperties 执行器配置 配置完成application.xml有提示 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方 法才可以,而使用@Value注解修饰的字段不需要提供set方法

整合Mabatis

1添加Mybatis的起步依赖

    <!--mybatis起步依赖-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.1.1</version>
    </dependency>

2添加数据库驱动坐标(不确定数据库)

    <!-- MySQL连接驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId> 
    </dependency>

3数据库连接信息

数据库连接信息 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=htoa

4bean 5mapper

<mapper namespace="com.mapper.UserInterFace">
<select id="selectList" resultType="user">
    select * from user
</select>
</mapper>

6放入application文件

配置mybatis信息 spring集成Mybatis环境 #pojo别名扫描包 mybatis.type-aliases-package=com.domain 加载Mybatis映射文件 mybatis.mapper-locations=classpath:com/mapper/*.xml

@Mapper
public interface UserInterFace {

public List<User> selectList();
}

@Controller
public class MybatisController {

@Autowired
public UserInterFace userInterFace;

@RequestMapping("/query")
@ResponseBody
public List<User> findAll() {
   List<User> users = userInterFace.selectList();
    System.out.println(users);
   return users;
}
}

RestController <> Controller和ResponseBody

整合问题:

1 This application has no explicit mapping for /error, so you are seeing this as a fallback.

启动类放的位置不对,启动类所在的package必需要包含Controller所在的package,当然直接把启动类放在项目最外层package中就最稳妥不过了

2 如何重新加载Spring Boot上的更改,而无需重新启动服务器 www.jianshu.com/p/c16200740…

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-devtools</artifactId>
 <optional>true</optional>
</dependency>

3 java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.

解决 spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/htoa?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8

4 Invalid bound statement (not found): com.example.springbootssmtest.mapper.UsersMapper.selectAll

检查resource目录的下级目录是否为一级一级新建 application.properties配置

5 org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.springboot.demo.mapper.UserMapper.findAll'. It's likely that neither a Result Type nor a Result Map was specified.

@Mapper

25 tag

SpringMVC 1 启动器

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
      
 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

2 覆盖配置 server.port=8088 3 启动类 4 controller 5 静态资源访问 static 6 配置拦截器

自定义拦截器 /** * 拦截器 / @Component public class MyIntercepter implements HandlerInterceptor { /* * 前置方法 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("前置方法正在执行"); return true; }

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("后置方法正在执行");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("完成方法正在执行");
}
}

@Configuration // 配置类
public class WebMvcConfiggution implements WebMvcConfigurer {

@Autowired
private MyIntercepter myIntercepter;
/**
 *
 * @param registry 拦截器 /** 任意级别
 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myIntercepter).addPathPatterns("/**");
}
}

7 具体日志

logging.level.org.springframework=DEBUG

数据源 jdbc启动器 1 application配置

spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/htoa?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=htoa

	<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

mybatis

	<dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>

1 application配置

mybatis.type-aliases-package=com.springboot mybatis.mapper-locations=classpath:com.springboot.demo.mybatis.mapper/*.xml

2 接口 @Mapper

3 mapper文件

4 Controller调用

事务

@Transactional