springboot源码解析一:环境准备

章节目录

一:环境准备

  1. Java8
    新特性:
  • Lambda表达式
  • Stream操作
  • 接口默认&静态方法
  • 方法引用
  • 重复注解
  • 类型注解
  • 日期&时间API
  • base64加密解密API
  • 数组并行操作
  • JVM新增元空间
    推荐书籍:《Java 8实战》
  1. Maven3.3
  • 依赖管理
  • 项目构建
  • 生命周期
  • 插件机制
    推荐书籍:《Maven实战》
  1. Intellij IDEA
  • 强大的整合能力:如git、maven、tomcat、等等
  • 提示功能快速、便捷
  • 快捷键方便
  • 简介易用
    推荐资料:IntelliJ IDEA官方文档;ItelliJ IDEA使用技巧,慕课网上的。
  1. Mysql5.7+
    Mysql优点:
  • 性能卓越
  • 服务稳点:双十一都是用的mysql
  • 开放的源代码
  • 社区活跃
    书籍推荐:《高性能MySQL》

二:动手搭建SSM与SpringBoot框架对比

2.1 SSM框架介绍

Spring+SpringMVC+MyBatis

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 打开IDEA,点击+Create New Project

  2. 左侧选择Maven 右侧勾选Create from archetype,选择webapp后缀的archetypes,Next

  3. GroupId:com.mooc,ArtifactId:ssm,Version:默认;Next,Next,Finash

  4. 新建Directory:main/java/com/mooc|main/resources;main/webapp/WEB-INF

  5. pom.xml中添加jar包文件
    IDEA 不显示 Maven 插件 mybatis-generator 解决
    maven命令下载jar包

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <mybatis.version>3.2.8</mybatis.version>
        <mybatis.spring.version>1.2.2</mybatis.spring.version>
        <mysql.version>5.1.32</mysql.version>
        <spring.version>4.2.6.RELEASE</spring.version>
    </properties>
    <!--在<dependencies>中新增start-->
    	<!--SpringMVC-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>
        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis.spring.version}</version>
        </dependency>
    
        <!-- MySql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
    
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 数据库连接池 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5-pre10</version>
        </dependency>
        <!--servlet、 jstl-->
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.25</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.servlet</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
    
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
    <!--在<dependencies>中新增end-->
    <plugins>
          <plugin>
               <groupId>org.mybatis.generator</groupId>
               <artifactId>mybatis-generator-maven-plugin</artifactId>
               <version>1.3.5</version>
               <dependencies>
                   <dependency>
                       <groupId>mysql</groupId>
                       <artifactId>mysql-connector-java</artifactId>
                       <version>5.1.38</version>
                   </dependency>
               </dependencies>
           </plugin>
           <plugin>
               <groupId>org.mortbay.jetty</groupId>
               <artifactId>jetty-maven-plugin</artifactId>
               <version>8.1.16.v20140903</version>
               <configuration>
                   <connectors>
                       <connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
                           <port>8080</port>
                       </connector>
                   </connectors>
                   <stopKey />
                   <stopPort />
               </configuration>
           </plugin>
       </plugins>
    
  6. 新建web.xml,并配置spring启动文件,springmvc文件,编码,开启restful

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>Archetype Created Web Application</display-name>
    <!--1. 启动Spring容器-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--2. Spring MVC 前端控制器 DispatcherServlet-->
    <servlet>
    	<!--名称 -->
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- Servlet类 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 启动顺序,数字越小,启动越早 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <!--3. 字符编码, 放在所有过滤器之前-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--4. 使用Rest风格的URL-->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
  1. resource下新建applicaitonContext.xml,并配置:数据源,
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="com.mooc">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--数据源-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="minPoolSize" value="${jdbc.miniPoolSize}"/>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
        <property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>
        <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>

        <property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}"/>
        <property name="acquireRetryDelay" value="${jdbc.acquireRetryDelay}"/>
        <property name="testConnectionOnCheckin" value="${jdbc.testConnectionOnCheckin}"/>
        <property name="automaticTestTable" value="${jdbc.automaticTestTable}"/>
        <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
        <property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"/>

    </bean>


    <!--配置和Mybatis整合-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--指定mybatis全局配置文件的位置-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置扫描器 , 将Mybatis接口的实现加入到IOC容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--扫描所有的dao接口,加入到IOC容器中-->
        <property name="basePackage" value="com.mooc.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
</beans>
  1. resource下新建db.properties,并配置:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl = jdbc:mysql://localhost:3306/test
jdbc.user = root
jdbc.password = 123456
jdbc.miniPoolSize = 1
jdbc.maxPoolSize = 20
jdbc.initialPoolSize = 1
jdbc.maxIdleTime = 25000
jdbc.acquireIncrement = 1

jdbc.acquireRetryAttempts = 30
jdbc.acquireRetryDelay = 1000
jdbc.testConnectionOnCheckin = true
jdbc.automaticTestTable = c3p0TestTable
jdbc.idleConnectionTestPeriod = 18000
jdbc.checkoutTimeout=3000
  1. 安装mysql并新建数据库test,新建表user
DROP TABLE IF EXISTS `demo`;
CREATE TABLE `demo`  (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `adress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `demo` VALUES (1, '张三', 12, '中国');
SET FOREIGN_KEY_CHECKS = 1;
  1. resource下新建mybatis-config.xml并配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.mooc.bean"/>
    </typeAliases>

    <!-- 加载 映射文件 -->
    <mappers>
        <mapper resource="mapper/DemoMapper.xml" />
    </mappers>
</configuration>
  1. WEB-INF下新建dispatcherServlet-servlet.xml,并配置。
  • 如果将此xml文件新建到resource目录下需要在web.xml中前端控制器servlet中添加如下代码
<init-param>
   <!--SpringMVC配置参数文件的位置 -->
    <param-name>contextConfigLocation</param-name>
    <!--默认名称为ServletName-servlet.xml -->
    <param-value>classpath*:dispatcherServlet-servlet.xml</param-value>
</init-param>
  1. mooc下新建controller、mapper文件夹
  2. resource下新建generatorConfig.xml,并配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
                        password="root">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="com.mooc.bean"
                            targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.mooc.mapper"
                             targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 指定数据库表 -->
        <table schema="demo" tableName="demo"></table>
    </context>
</generatorConfiguration>
  1. resource下新建mapper
  2. pom中配置generator的plugin,在Maven窗口中就可以进行自动生成bean、dao、xml
  3. mooc下新建service服务类,新建DemoService:用于读取服务,添加@Componet注解
package com.mooc.service;

import com.mooc.bean.Demo;
import com.mooc.mapper.DemoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class DemoService {

    @Autowired
    private DemoMapper demoMapper;

    public Demo getDemoById(int id) {
        return Optional.ofNullable(demoMapper.selectByPrimaryKey(id)).orElse(null);
    }

}

  1. 新建DemoController
package com.mooc.controller;

import com.mooc.bean.Demo;
import com.mooc.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Optional;

@Controller
@RequestMapping("/demo")
public class DemoController {

    @Autowired
    private DemoService demoService;

    @RequestMapping("/hello/{id}")
    @ResponseBody
    public String hello(@PathVariable(value = "id") int id) {
        return Optional.ofNullable(demoService.getDemoById(id)).map(Demo::toString).orElse("empty String");
    }
}
  1. pom中配置Jetty。
  2. Maven窗口中点击:jetty:run。
  3. 浏览器窗口输入localhost:8080/demo/hello/1.html
  4. SSM搭建流程:
    Start=》引入jar包=》web.xml=》applictionContext.xml=》dispatcherServlet.xml=》mybatis-config.xml=》配置容器=》编写服务类=》编写控制类=》end
  5. SSM搭建总结
  • 耗时长
  • 配置文件繁琐
  • jar包管理
  • 新手不友好

2.2 SpringBoot框架搭建

Spring Boot口号:build anything()

  1. +Create New Project
  2. 左侧选择Spring Initializr(spring初始化器),Next
  3. Group:com.mooc,Artifact:sb2,Next
  4. 左侧选web,右侧勾选:spring web starter
  5. 左侧选sql,右侧勾选:Mybatis FrameWork,Finash
  6. resources下新建generatorConfig.xml,并配置(见2.1,需要稍作修改包名)
  7. com.mooc.sb2下新建bean和mapper文件夹
  8. pom中配置generator的plugin
  9. Maven窗口中会出现mybaits-generator,点击generator生成bean,dao,xml
  10. 配置application.properties
server.port=8080
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.mooc.sb2.bean
mybatis.configuration.map-underscore-to-camel-case=true
  1. pom中配置mysql
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>
</dependencies>
  1. Sb2Application中配置@MapperScan(“com.mooc.sb2.mapper”)
  2. com.mooc.sb2下新建service文件夹,并新建DemoService(同2.1)
  3. com.mooc.sb2下新建controller文件夹,并新建DemoController类(同2.1)
  4. 在Sb2Application类,添加注解@MapperScan(“com.mooc.sb2.mapper”)运行启动
  5. 浏览器中输入localhost:8080/demo/hello/1
  6. Spring Boot搭建流程
    start=》引入starter=》application.properties=》编写服务类=》编写控制类=》end
  7. Spring Boot搭建总结
  • 耗时短
  • 配置文件简介
  • 不关注版本管理
  • 易上手

三:SpringBoot启动流程介绍

  • 一行完成启动
SpringApplication.run(SourceApplication.class, args);

点击run进去看源码,可以看到如下调用流程

	public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		// 调用了重载方法run
		return run(new Class<?>[] { primarySource }, args);
	}
	// 再点run==》
	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		// 第一步:新建了个当前对象,把SourceApplication类传了进去
		// 第二步:运行,把args传了进去
		return new SpringApplication(primarySources).run(args);
	}
	// 先看第一步,点进去构造方法
	public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

启动流程

  1. 框架初始化
    • 配置资源加载器
    • 配置primarySources
    • 应用环境检测
    • 配置系统初始化器
    • 配置应用监听器
    • 配置main方法所在类
  2. 框架启动
    计时器开始计时
    =》Headless模式赋值
    =》发送ApplicationStartingEvent
    =》配置环境模块
    =》发送ApplicationEnvironmentPreparedEvent
    =》打印banner
    =》创建应用上下文对象
    =》初始化失败分析器
    =》关联springboot组件与应用上下文对象
    =》发送ApplicationContextInitializedEvent
    =》加载sources到context发送ApplicationPreparedEvent
    =》刷新上下文
    =》计时器停止计时
    =》发送ApplicationStarteEvent
    =》调用框架启动扩展类
    =》发送ApplicationReadyEvent
    =》完成
  • 自动化装配(属于框架启动,抽出来讲解)
    • 收集配置文件的配置工厂类
    • 加载组件工厂
    • 注册组件内定义bean
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值