今天记录下对springBoot的初步使用。
笔者不知道各位同道中人有多少大牛和多少新嫩,新嫩无疑是幸运的,入手学习的第一套框架极大可能就是SpringMvc+spring+mybatis。不用经历struct2和hibernate的洗礼,不用面对曾今的一堆繁琐的xml,至少你是在大量使用注解的时代。
笔者属于新老交接的时间2014开始接触java,是学校专业,但基础不好,一路被老学长坑带学了各种古老的东西。
无论咋样,现在说说springboot。
springboot的理念是:习惯优于配置,说白了,就是让大家不要标新立异,弄个马沙特风格来构建项目,用spring的开发者,都使厂家提供的风格来构建项目,而这个风格是由大部分程序员多年形成的习惯而来的。
然后不要把springboot理解为一种新技术,它只是巧妙的运用了spring4之后提供的通过代码来自动完成配置,来替换了xml配置
笔者案例的springboot版本为1.5.10
一:入门案例
新建maven项目,pom文件为:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gccSpringBoot</groupId>
<artifactId>gccSpringBoot</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>gccSpringBoot Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主要是引入starter-web,这东西会关联下载springWeb所需的jar包。
然后就是新建启动文件:
package com.gcc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by gcc on 2018/2/27.
*
* springBoot会扫描此运行文件以及子目录的注解
*
* @RestController 注解相当于@ResponseBody + @Controller合在一起的作用。
* 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,配置的视图解析器不起作用,返回的内容就是Return 里的内容。
*
* @EnableAutoConfiguration ,这个注解告诉Spring Boot根据添加的jar依赖猜测你想如何配置Spring。
* 由于pom内配置的是 spring-boot-starter-web,带有Tomcat和SpringMVC,所以注解将假定你正在开发一个web应用,并对Spring进行相应地设置。
*
*/
@RestController
@EnableAutoConfiguration
public class Demo1 {
@RequestMapping("/")
public String home(){
return "welcome to home";
}
/**
* main方法通过调用run ,将业务委托给了Spring Boot的SpringApplication类。
* SpringApplication将引导我们的应用,启动Spring,相应地也会启动自动配置的Tomcat服务器。
* 我们需要将 Example.class 作为参数传递给run方法,以此告诉SpringApplication谁是主要的Spring组件,并传递args数组以暴露所有的命令行参数。
*/
public static void main(String[] args) throws Exception {
SpringApplication.run(Demo1.class,args);
}
}
代码功能已经注释的很清楚了,关键就是@EnableAutoConfiguration,会根据pom文件内容来选择执行哪些配置,具体怎么实现可以进入注解代码查看,对理解springboot运行原理很有帮助。
main为入口,右击此类运行run,同时就会运行内置的tomcat,控制台打印一个Banner图案和运行日志:
之后再浏览器输入localhost:8080,就会根据代码逻辑显示welcom to home的字样
这样一个web项目就初步构建完成了,类别曾今整合structs2和springMvc是不是快速了很多,连web.xml都没有任何配置
二:小项目构建案例
当然只是构建web项目是不足以开发的,我们还需要前端和数据库
先说前端,springboot建议使用各类前端模板,常用的有freemarker和thymeleaf,推荐的是thymeleaf。至于为什么不用jsp,百度有一推理由,硬伤什么的笔者也看了,如下:
om.xml中的javax.servlet.jsp.jstl是用于支持JSP标签库的,在Web2.5的容器中没有问题,单当你的容器是Web3.0或以上版本时,就会出问题。 这是个非常坑爹的问题。
javax.servlet.jsp.jstl会自动加载依赖servlet-api-2.5.jar, 而且会在实际运行时把支持Web3.0的3.1版本的javax.servlet-api覆盖掉。即使你在pom.xml显示的在加入3.1版本的javax.servlet-api也没用。导致SpringBoot应用抛出Runtime exception运行错误。
这是一个不可调和的矛盾,要吗不用javax.servlet.jsp.jstl,要吗不用Web3.0。
但绝大多数情况下,jstl标签库不是必须的,而Web3.0是必须的。替代方式就是不用JSP,改用Thyemeleaf吧
spring厂家,呵呵:噫吁嚱,整合有bug大家不要用,遇到麻烦概不负责。
然后百度了一堆前端模板的好处安慰自己,模板好啊,html格式的,前端多方便测试,然而作为一个前端,后台,数据库都自个儿搞的程序员根本体会不到模板的优势。
结论,笔者使用thymeleaf
再说数据库,springboot提供的数据库操作方式有多种,例如JPA,但笔者自从使用mybatis后一直很习惯这种方式,所以这里也使用mybais。
下面是案例项目结构,使用的是idea开发工具:
使用thymeleaf和mybatis先要引用对应的jar包,这里额外再添加了dbcp2连接池:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gcc</groupId>
<artifactId>thymeleaf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>thymeleaf</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!--数据库连接jdbc依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql链接依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这里jdbc和devtools可以去掉,在使用jdbc方式时,配置mybatis然后用xml文件写sql会意外报错(使用注解CRUD没有问题);devtools用于热部署,测试时候没有生效。这两个问题待解决,有清楚的请告知笔者。
所需jar包齐全后,这里先串连thymeleaf,测试实体如下:
package com.gcc.entity;
/**
* Created by gcc on 2018/2/28.
*/
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
准备的测试数据如下:
package com.gcc.web;
import com.gcc.entity.Person;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;
/**
* Created by gcc on 2018/2/28.
*/
@Controller
@SpringBootApplication
public class thymeleafDemoController {
@RequestMapping("/home")
public String index(Model model){
Person single = new Person("sky",21);
List<Person> personList = new ArrayList<Person>();
Person p1 = new Person("OK_mary",27);
Person p2= new Person("jack",16);
Person p3= new Person("faker",22);
personList.add(p1);
personList.add(p2);
personList.add(p3);
model.addAttribute("singlePerson",single);
model.addAttribute("people",personList);
return "index";
}
}
这里额外说明一个注解,@SpringBootApplication,这个注解本身没有特别意义,它主要用于简化,它主要包含了@EnableAutoConfiguration和@ComponentScan。
准备的测试页面如下:
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta content="text/html;charset=UTF-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>thymeleaf</title>
<link th:href="@{bootstrap_3/css/bootstrap.min.css}" rel="stylesheet"/>
<link th:href="@{bootstrap_3/css/bootstrap-theme.min.css}" rel="stylesheet"/>
</head>
<body>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">访问人</h3>
</div>
<div class="panel-body">
<span th:text="${singlePerson.name}"></span>
</div>
</div>
<div th:if="${not #lists.isEmpty(people)}">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">列表</h3>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item" th:each="person:${people}">
<span th:text="${person.name}"></span>
<span th:text="${person.age}"></span>
<button class="btn" th:οnclick="'getName(\''+${person.name}+'\');'">获得名字</button>
</li>
</ul>
</div>
</div>
</div>
<script th:src="@{jquery/jquery-3.3.1.min.js}" type="text/javascript"></script>
<script th:src="@{bootstrap_3/js/bootstrap.min.js}" type="text/javascript"></script>
<script th:inline="javascript">
var single=[[${singlePerson}]];
alert(single.name+"/"+single.age)
function getName(name) {
alert(name)
}
</script>
</body>
</html>
thymeleaf其实和jsp或者html都很类似,通过第一行声明,把html从静态转换为动态,也就是说可以用某些表达式填充数据。需要转换的数据用th:开头。
通过"@{}"引用静态资源,这里引用了bootstrap和jquery
通过${}访问model中的属性
通过th:each来循环,类似c:foreach
通过th:if来做判断,也支持>,<,>=,<=,==,!=
通过th:inline="Javascript",使能在js里获取model的数据,通过[[${}]]来获取实际的值
至于contraller是如何将数据传递到视图的,这也是由于默认配置,配置类部分代码如下:
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
最后是启动入口,这里先不用关心内容,其内容是用于之后的数据库测试:
package com.gcc;
import com.gcc.dao.TestDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//第三个是开启缓存
@SpringBootApplication
@RestController
@EnableCaching
public class ThymeleafApplication {
@Autowired
TestDao testDao;
@Value("${book.name}")
private String name;
@RequestMapping("/")
public String home(){
return "welcome to home the book's name is "+name;
}
@RequestMapping("/test")
public String testMybatis(){
return testDao.find().get(0).getName();
}
@RequestMapping("/testXml")
public String testMybatisXml(){
return testDao.findByXml().get(0).getName();
}
public static void main(String[] args) {
SpringApplication.run(ThymeleafApplication.class, args);
}
}
启用后访问home路径,跳转页面如下:
可以点击测试,是否js也获取了model的数据,正常则串连thymeleaf完成。
下面是串连mybatis,首先是配置文件,application.properties:
#server.port=8443
#用户会话session过期时间,单位是秒
server.session.timeout=3600
spring.profiles.active=dev
server.context-path=/
#server.ssl.key-store=.keystore
#server.ssl.key-store-password=101213
#server.ssl.key-store-type=JKS
#server.ssl.key-alias=tomcat
# 下面是通过此配置文件注入的数据,仅做测试
book.name=jack
book.price=20
#debug=true
#测试时关掉页面模板缓存
spring.thymeleaf.cache=false
#jdbc
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://127.0.0.1:3307/spring_boot?useUnicode=true&characterEncoding=utf8
#jdbc.username=root
#jdbc.password=123456
#jdbc.maxActive=2335
#jdbc.maxIdel=120
#jdbc.maxWait=100
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3307/spring_boot?useUnicode=true&characterEncoding=utf8
spring.datasource.dbcp2.max-total=2335
spring.datasource.dbcp2.max-idle=120
spring.datasource.dbcp2.max-wait-millis=100
mybatis.mapper-locations=classpath:mappings/*.xml
#号后的是注释掉的。
主要是最后几行,配置了数据驱动,数据库用户名密码,数据方式(连接池),路径,编写sql的xml文件路径
然后是测试用的dao:
package com.gcc.dao;
import com.gcc.entity.Person;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* Created by gcc on 2018/2/28.
*/
@Mapper
public interface TestDao {
@Select("select * from users;")
public List<Person> find();
public List<Person> findByXml();
}
@Mapper注解会告诉mybatis来扫描自己,并成为一个bean
其中find方法是通过注解来编写sql,findByXml是通过xml来编写sql。
xml如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gcc.dao.TestDao">
<select id="findByXml" resultType="com.gcc.entity.Person">
select * from users
</select>
</mapper>
然后就可以通过入口controller来测试两种方式的查询,结果正常则表示串连mybatis完成。
这里数据库是mysql。
感谢各位观看,同道中人请多交流,笔者是老新嫩