springboot源码解析一:环境准备
章节目录一:环境准备Java8新特性:Lambda表达式Stream操作接口默认&静态方法方法引用重复注解类型注解日期&时间APIbase64加密解密API数组并行操作JVM新增元空间推荐书籍:《Java 8实战》Maven3.3依赖管理项目构建生命周期插件机制推荐书籍:《Maven实战》Intellij IDEA强大的整合能力:如git、maven、tomcat、等等提示功能快速
·
章节目录
一:环境准备
- Java8
新特性:
- Lambda表达式
- Stream操作
- 接口默认&静态方法
- 方法引用
- 重复注解
- 类型注解
- 日期&时间API
- base64加密解密API
- 数组并行操作
- JVM新增元空间
推荐书籍:《Java 8实战》
- Maven3.3
- 依赖管理
- 项目构建
- 生命周期
- 插件机制
推荐书籍:《Maven实战》
- Intellij IDEA
- 强大的整合能力:如git、maven、tomcat、等等
- 提示功能快速、便捷
- 快捷键方便
- 简介易用
推荐资料:IntelliJ IDEA官方文档;ItelliJ IDEA使用技巧,慕课网上的。
- Mysql5.7+
Mysql优点:
- 性能卓越
- 服务稳点:双十一都是用的mysql
- 开放的源代码
- 社区活跃
书籍推荐:《高性能MySQL》
二:动手搭建SSM与SpringBoot框架对比
2.1 SSM框架介绍
Spring+SpringMVC+MyBatis
-
打开IDEA,点击+Create New Project
-
左侧选择Maven 右侧勾选Create from archetype,选择webapp后缀的archetypes,Next
-
GroupId:com.mooc,ArtifactId:ssm,Version:默认;Next,Next,Finash
-
新建Directory:main/java/com/mooc|main/resources;main/webapp/WEB-INF
-
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>
-
新建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>
- 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>
- 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
- 安装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;
- 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>
- 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>
- mooc下新建controller、mapper文件夹
- 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>
- resource下新建mapper
- pom中配置generator的plugin,在Maven窗口中就可以进行自动生成bean、dao、xml
- 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);
}
}
- 新建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");
}
}
- pom中配置Jetty。
- Maven窗口中点击:jetty:run。
- 浏览器窗口输入localhost:8080/demo/hello/1.html
- SSM搭建流程:
Start=》引入jar包=》web.xml=》applictionContext.xml=》dispatcherServlet.xml=》mybatis-config.xml=》配置容器=》编写服务类=》编写控制类=》end - SSM搭建总结
- 耗时长
- 配置文件繁琐
- jar包管理
- 新手不友好
2.2 SpringBoot框架搭建
Spring Boot口号:build anything()
- +Create New Project
- 左侧选择Spring Initializr(spring初始化器),Next
- Group:com.mooc,Artifact:sb2,Next
- 左侧选web,右侧勾选:spring web starter
- 左侧选sql,右侧勾选:Mybatis FrameWork,Finash
- resources下新建generatorConfig.xml,并配置(见2.1,需要稍作修改包名)
- com.mooc.sb2下新建bean和mapper文件夹
- pom中配置generator的plugin
- Maven窗口中会出现mybaits-generator,点击generator生成bean,dao,xml
- 配置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
- pom中配置mysql
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
- Sb2Application中配置@MapperScan(“com.mooc.sb2.mapper”)
- com.mooc.sb2下新建service文件夹,并新建DemoService(同2.1)
- com.mooc.sb2下新建controller文件夹,并新建DemoController类(同2.1)
- 在Sb2Application类,添加注解@MapperScan(“com.mooc.sb2.mapper”)运行启动
- 浏览器中输入localhost:8080/demo/hello/1
- Spring Boot搭建流程
start=》引入starter=》application.properties=》编写服务类=》编写控制类=》end - 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();
}
启动流程
- 框架初始化
- 配置资源加载器
- 配置primarySources
- 应用环境检测
- 配置系统初始化器
- 配置应用监听器
- 配置main方法所在类
- 框架启动
计时器开始计时
=》Headless模式赋值
=》发送ApplicationStartingEvent
=》配置环境模块
=》发送ApplicationEnvironmentPreparedEvent
=》打印banner
=》创建应用上下文对象
=》初始化失败分析器
=》关联springboot组件与应用上下文对象
=》发送ApplicationContextInitializedEvent
=》加载sources到context发送ApplicationPreparedEvent
=》刷新上下文
=》计时器停止计时
=》发送ApplicationStarteEvent
=》调用框架启动扩展类
=》发送ApplicationReadyEvent
=》完成
- 自动化装配(属于框架启动,抽出来讲解)
- 收集配置文件的配置工厂类
- 加载组件工厂
- 注册组件内定义bean
更多推荐
已为社区贡献1条内容
所有评论(0)