springBoot入门
1 springBoot
1.1 SpringBoot简介
Spring Boot让我们的Spring应用变的更轻量化。比如:你可以仅仅依靠一个Java类来运行一个Spring引用。你也可以打包你的应用为jar并通过使用java -jar来运行你的Spring Web应用。
Spring Boot的主要优点:
为所有Spring开发者更快的入门
开箱即用,提供各种默认配置来简化项目配置
内嵌式容器简化Web项目
没有冗余代码生成和XML配置的要求
本章主要目标完成Spring Boot基础项目的构建,并且实现一个简单的Http请求处理,通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。
1.2 系统要求
Java1.8及以上
Spring Framework 4.1.5及以上
本文采用Java 1.8.0_73、Spring Boot 1.3.3调试通过。
2 快速入门
2.1 创建一个maven工程
名为“springBoot-helloWorld”类型为jar的工程项目
直接next到下一步点击finish。
新建maven项目如下:
2.2 pom文件引入依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent> <dependencies> <!--SpringBoot web 组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> |
spring-boot-starter-parent作用 spring-boot-starter-parent是一个特殊的starter,它用来提供相关的Maven默认依赖。使用它之后,常用的包依赖可以省去version标签。 spring-boot-starter-web作用 springweb 核心组件 spring-boot-maven-plugin作用 在添加了该插件之后,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行。这在很大程度上简化了应用的部署,只需要安装了 JRE 就可以运行。 |
如下:
2.3 编写HelloWorld服务
包名为:com.springBoot;类名为:HelloController
2.4 编写启动类
包名为:com ;类名为:StartAPP
注:这里的启动类必须要在所有的类的上一级或同级,注解@SpringBootApplication才能扫描到。
2.5 启动应用程序
2.5.1 方式一:
直接运行main方法:springBoot内部自带tomcat服务器
出现如下,表示服务器已经启动:
2.5.2 方式二:
打包项目:然后利用cmd命令:java –jar jar包名称
打包:双击package即可
出现如下:表示打包成功
切换到jar包所在目录,利用命令java –jar jar包名运行:
2.6 查看结果
打开浏览器,在浏览器输入:http://localhost:8080/hello/world,结果如下:
2.7 上面所用到的注解解释
2.7.1 @SpringBootApplication
他相当于@Configuration、@EnableAutoConfiguration、ComponentScan三个注解之和。
其中:
@ComponentScan:自动扫描符合条件的组件或bean;让spring Boot扫描到Configuration类并把它加入到程序上下文。
@Configuration :IOC容器配置,等同于spring的XML配置文件;使用Java代码可以检查类型安全。
@EnableAutoConfiguration :自动配置,将所有符合自动配置的bean加载到IOC容器中。
2.7.2 @RestController
@RestController:注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直接填入HTTP响应体中,是REST风格的控制器。
@ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。在使用@RequestMapping后,返回值通常解析为跳转路径,加上@Responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@Responsebody后,会直接返回json数据。该注解一般会配合@RequestMapping一起使用。
@Controller:用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。
2.7.3 @RequestMapping
@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。
3 web开发
3.1 静态资源访问
在我们开发Web应用的时候,需要引用大量的js、css、图片等静态资源。
默认配置
Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则:
/static
/public
/resources
/META-INF/resources
举例:我们可以在src/main/resources/目录下创建static,在该位置放置一个图片文件。启动程序后,尝试访问http://localhost:8080/D.jpg。如能显示图片,配置成功。
启动程序并访问:
3.2 全局捕获异常
/**
* @ExceptionHandler 表示拦截异常
* • @ControllerAdvice 是 controller 的一个辅助类,最常用的就是作为全局异常处理的切面类
* • @ControllerAdvice 可以指定扫描范围
* • @ControllerAdvice 约定了几种可行的返回值,如果是直接返回 model 类的话,需要使用 @ResponseBody 进行 json 转换
* o 返回 String,表示跳到某个 view
* o 返回 modelAndView
* o 返回 model + @ResponseBody
*/ @ControllerAdvice public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Map<String,Object> exceptionHandler(){
Map<String,Object> map = new HashMap<String, Object>();
map.put("errorCode","101");
map.put("errorMsg","系统错误");
return map;
}
} |
3.3 渲染web页面
渲染Web页面
在之前的示例中,我们都是通过@RestController来处理请求,所以返回的内容为json对象。那么如果需要渲染html页面的时候,要如何实现呢?
模板引擎
在动态HTML实现上Spring Boot依然可以完美胜任,并且提供了多种模板引擎的默认配置支持,所以在推荐的模板引擎下,我们可以很快的上手开发动态网站。
Spring Boot提供了默认配置的模板引擎主要有以下几种:
• Thymeleaf
• FreeMarker
• Velocity
• Groovy
• Mustache
Spring Boot建议使用这些模板引擎,避免使用JSP,若一定要使用JSP将无法实现Spring Boot的多种特性,具体可见后文:支持JSP的配置;
当你使用上述模板引擎中的任何一个,它们默认的模板配置路径为:src/main/resources/templates。当然也可以修改这个路径,具体如何修改,可在后续各模板引擎的配置属性中查询并修改。
3.4 使用FreeMarker模板引擎渲染web视图
3.4.1 pom文件引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> |
3.4.2 freemarker配置
新建application.properties文件
######################################################## ###FREEMARKER (FreeMarkerAutoConfiguration) ######################################################## spring.freemarker.allow-request-override=false spring.freemarker.cache=true spring.freemarker.check-template-location=true spring.freemarker.charset=UTF-8 spring.freemarker.content-type=text/html spring.freemarker.expose-request-attributes=false spring.freemarker.expose-session-attributes=false spring.freemarker.expose-spring-macro-helpers=false #spring.freemarker.prefix= #spring.freemarker.request-context-attribute= #spring.freemarker.settings.*= spring.freemarker.suffix=.ftl (好像设置为html不可以) spring.freemarker.template-loader-path=classpath:/templates/ #comma-separated list #spring.freemarker.view-names= # whitelist of view names that can be resolved |
3.4.3 后台代码
在HelloController中加上如下代码:
/**
* 使用Freemarker模板引擎渲染web视图
* @param map
* @return
*/ @RequestMapping("/index") public String index(Map<String,Object> map){
map.put("name","张志强。。。");
map.put("age","18");
map.put("say","我叫张志强,今年18岁。。");
return "aa";//aa是跳转到aa.flt页面
} |
3.4.4 前台代码
在src/main/resources/创建一个templates文件夹,然后在文件夹下面创建aa.flt文件,内容如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title></title>
</head>
<body>
<h1>前台页面aa.ftl</h1>
我叫:${name}
<br>
今年:${age}
<br>
我想说:${say} </body>
</html> |
3.4.5 测试
启动服务程序——>在页面输入http://localhost:8080/hello/index后成功显示出页面:
3.4.6 Freemarker其他用法
主要就是判断、集合;
例如:
后端代码:
@RequestMapping("/freemarkerIndex") public String freemarkerIndex(Map<String, Object> result) {
result.put("name", "王坤");
result.put("sex", "1");
List<String> listResult = new ArrayList<String>();
listResult.add("zhangsan");
listResult.add("lisi");
result.put("listResult", listResult);
return "bb";
} |
前端代码:在templates文件夹下面新建bb.flt文件,内容如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title></title>
</head>
<body>
<h1>前台页面</h1>
${name}
<#--条件判断-->
<#if sex=="1">
男
<#elseif sex=="2">
女
<#else>
其他
</#if>
<br>
<#--显示集合数据-->
<#list listResult as list1>
<br>
<h1>1号 </h1>
${list1}
<br>
</#list> </body>
</html> |
启动服务——>打开浏览器输入:http://localhost:8080/hello/freemarkerIndex显示页面:
3.5 使用JSP渲染web视图
3.5.1 pom文件引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency> |
3.5.2 在application.properties创建以下配置
# 页面默认前缀目录 spring.mvc.view.prefix=/WEB-INF/jsp/ # 响应页面默认后缀 spring.mvc.view.suffix=.jsp |
3.5.3 后端代码
注意:创建SpringBoot整合JSP,一定要为war类型,否则会找不到页面.
在包controller下面新建IndexController类:
@Controller public class IndexController {
@RequestMapping("/index")
public String index(Map<String,Object> map) {
map.put("name","张三");
map.put("age","22");
return "index";
}
} |
如下:
3.5.4 前台jsp页面
注意:Jsp页面文件夹必须建立main文件夹下面webapp文件夹——>jsp文件夹下面创建*.jsp。
如下所示目录结构:
3.5.5 运行并测试
运行:启动StartApp,并打开浏览器输入网址:
注:这里的整合jsp与freemarker模板引擎并不冲突(由于刚开始将WEB-INF放在了resources下面,导致一直报错,后来调整了目录结构就好了。)
4 数据访问
4.1 springBoot整合JdbcTemplate
4.1.1 pom文件引入
<!--整合JDBC访问数据--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> |
4.1.2 application.properties新增配置
spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123465 spring.datasource.driver-class-name=com.mysql.jdbc.Driver |
4.1.3 创建UserService类
先创建service包,在创建UserService类
@Service public class UserService {
//导入JdbcTemplate模板
@Autowired
private JdbcTemplate jdbcTemplate;
public void createUser(String name,Integer age){
jdbcTemplate.update("insert into users values(null,?,?);",name,age);
System.out.println("成功添加一个用户。。");
}
} |
4.1.4 创建UserController类调用UserService的方法
@Controller public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/insertUser")
public void insertUser(){
userService.createUser("张三三",22);
}
} |
4.1.5 创建数据库
4.1.6 运行程序并测试
测试结果如下:
注意: spring-boot-starter-parent要在1.5以上。
4.2 springBoot整合mybatis
4.2.1 pom文件引入
在上面之前建立的pom文件的依赖下再添加下面的mybatis依赖
<!--整合mybatis--> <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> |
4.2.2 配置文件引入
spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123465 spring.datasource.driver-class-name=com.mysql.jdbc.Driver |
4.2.3 Mapper代码
创建UserMapper类
@Mapper
@Repository//注解 public interface UserMapper {
@Select("SELECT * FROM USERS WHERE NAME = #{name}")
User findByName(@Param("name") String name);
//插入用户
@Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
} |
4.2.4 创建service层调用mapper层
public User findUserByName(String name){
User u = userMapper.findByName(name);
return u;
} public int insertUser(String name,int age){
return userMapper.insert(name,age);
} |
4.2.5 创建controller层代码
/**
* 添加用户
* @param name
* @param age
* @return
*/ @RequestMapping("/insertUser")
@ResponseBody public int insertUser(String name,int age){
return userService.insertUser(name,age);
} /**
* 根据姓名查询用户
* @param name
* @return
*/ @RequestMapping("/findUserByName")
@ResponseBody public User findUserByName(String name){
return userService.findUserByName(name);
} |
4.2.6 测试
运行并测试:
测试插:1:这里注意url拼接name不需要加“”,否则代入数据库的也包含“”。例如:
测试插入2:
测试查询:
4.3 springboot整合使用springjpa
4.3.1 pom文件引入依赖
<!--整合使用springjpa--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> |
4.3.2 创建Student实体类
@Entity(name = "student") public class Student {
@Id
@GeneratedValue//主键
private Integer sid;
@Column
private String sname;
@Column
private String sage; // ..get/set方法 } |
4.3.3 创建StudentDao
JpaRepository类中封装了对数据库的基本的增删改查方法。
public interface StudentDao extends JpaRepository<Student,Integer> {
} |
4.3.4 在 StudentController中新建代码
@RestController
@RequestMapping("/jpa") public class StudentController {
@Autowired
private StudentDao studentDao;
@RequestMapping("/findStudent")
public List<Student> findStudent(Integer id){
List<Student> allStu = studentDao.findAll();
for (int i = 0; i <allStu.size() ; i++) {
System.out.println(allStu.get(i).getSname());
}
return allStu;
}
//插入一个student
@RequestMapping("/insertStu")
public Student insertStu(Student stu){
Student student = studentDao.save(stu);
return student;
}
} |
4.3.5 启动项目测试
4.3.5.1 Jpa插入一个学生
学生表主键是:自增
这里sname与sage要与数据库字段对应上。
数据库:
4.3.5.2 查询所有学生
5 事务管理
5.1 springBoot整合事物管理
springboot默认集成事物,在主要在方法上加上@Transactional即可
5.2 SpringBoot分布式事物管理
使用spring-boot-starter-jta-atomikos 分布式事物管理
5.2.1 新增配置文件信息
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> |
6 缓存
6.1.1 pom文件引入
<!--配置缓存--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency> |
6.1.2 新建ehcache.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<!-- 默认配置 -->
<defaultCache maxElementsInMemory="5000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
memoryStoreEvictionPolicy="LRU" overflowToDisk="false" />
<cache name="baseCache" maxElementsInMemory="10000"
maxElementsOnDisk="100000" />
</ehcache> |
配置信息介绍
<!--配置信息说明-->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
--> |
6.1.3 代码使用Cacheable
@CacheConfig(cacheNames = "baseCache") public interface UserMapper { @Select("select * from users where name=#{name}") @Cacheable UserEntity findName(@Param("name") String name); } |
6.1.4 清除缓存
@Autowired private CacheManager cacheManager; @RequestMapping("/remoKey") public void remoKey() { cacheManager.getCache("baseCache").clear(); } |
6.1.5 启动加入缓存
在启动类中加入:
@EnableCaching // 开启缓存注解
6.2.1 POM.xml文件中添加依赖
<!--spring-boot-redis组件 --> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> |
6.2.2 添加redis配置
application.properties中配置Redis连接信息,如下:
#redis配置
# Redis数据库索引(默认为0,总共16个) spring.redis.database=0 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=0 |
Redis数据库:
6.2.3 后台封装redis业务代码
业务层代码:
package com.springBoot.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.List; /**
* springBoot -redis使用
*/ @Service public class RedisService {
@Autowired
StringRedisTemplate stringRedisTemplate ;
//封装resids保存数据的方法
public void setObject(String key,Object value){
if(StringUtils.isEmpty(key) || value ==null){
return ;
}
//判断是否String
if(value instanceof String){
String strValue=(String)value;
stringRedisTemplate.opsForValue().set(key, strValue);
}
//判断是否List
if(value instanceof List){
List<String> listValue=(List<String>)value;
for (String str:listValue) {
stringRedisTemplate.opsForList().leftPush(key, str);
}
}
}
//获取redis中的内容
public String getObject(String key){
return stringRedisTemplate.opsForValue().get(key);
}
//获取redis中内容 List
public List<String> lRange(String k, long l, long l1){
ListOperations<String, String> list = stringRedisTemplate.opsForList();
return list.range(k,l,l1);
}
} |
控制层代码:
package com.springBoot.controller;
import com.springBoot.service.RedisService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList; import java.util.List;
@RestController public class RedisController {
@Autowired
RedisService redisService;
@RequestMapping("/setString")
public String setString(String key,String value){
redisService.setObject(key, value);
return "success";
}
@RequestMapping("/setList")
public String setList(String key){
List list=new ArrayList();
list.add("lg");
list.add("30");
redisService.setObject(key, list);
return "success";
}
@RequestMapping("/getString")
public String getString(String key){
return redisService.getObject(key);
}
@RequestMapping("/getList")
public List<String> getList(String k, long l, long l1){
return redisService.lRange(k, l, l1);
}
} |
6.2.4 测试
6.2.4.1 先查看redis数据库内容:
6.2.4.2 存一个String类型的数据进去
启动程序:
查看数据库:
6.2.4.3 查询刚刚存进去的name
6.2.4.4 存一个list类型的对象(person)
查看数据库:
6.2.4.5 查询刚刚的list(person)
查询key=person的对象,从0到2,表示查询list下标从0开始到2的前三个对象。
7 其他内容
在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置
@Component
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}
}
启动加上@EnableAsync ,需要执行异步方法上加入 @Async
7.1.3 自定义参数
配置文件值
后台代码:在IndexController中
@Value("${name}") private String name;
@ResponseBody
@RequestMapping("/getValue") public String getValue() {
return name;
} |
7.1.3.1 测试
7.1.4 多环境配置
spring.profiles.active=pre |
application-dev.properties:开发环境 application-test.properties:测试环境 application-prod.properties:生产环境 |
7.1.5 修改端口号
server.port=8888
server.context-path=/springBoot
7.1.6 SpringBoot yml 使用
创建application.yml
注意:这里的冒号后面必须要有空格。
server:
port: 8090
# 全局路径设置
context-path: /springBoot
启动程序类:查看端口号已经是8090了。
查询redis中的name:
7.1.7 发布打包
使用mvn package 打包
使用java –jar 包名
如果报错没有主清单,在pom文件中新增
<build>
<plugins>
<plugin>
<!--打包-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<!--启动类配置-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.springBoot.StartApp</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> |