一 简介
初次接触springboot,最直观的感受是搭建项目几乎不需要任何配置文件,自带Tomcat容器,节省了很多开发和部署时间,项目也变得更加精简。
SpringBoot主要特性:
1 spring Boot Starter:它将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中;
2 自动配置:Spring Boot 的自动配置特性利用了Spring4对条件化配置的支持,合理的推测应用所需的bean并自动化配置他们;
3 命令行接口 : Spring Boot的CLI发挥了Groovy编程语言的优势,并结合自动配置进一步简化Spring应用的开发;
4 Actuator: 它为Spring Boot应用添加了一定的管理特性
下面简单介绍如何创建springboot项目。
二 运行环境
jdk1.8
tomcat8
maven4.0
三 搭建springboot项目
3.1 创建maven项目
首先创建一个maven项目,如何创建maven项目这里不多介绍,网上有很多教程。
项目结构如下图
3.2 在pom文件中加入springboot相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
首先在pom中添加一个parent项目,我们让项目的Maven构建基于Spring Boot starter parent,这样的话,我们就能受益于Maven的依赖管理功能,对于项目中的很多依赖,就没有必要明确声明版本号了,因为版本号会从parent中继承得到。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- <exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions> -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--常用库依赖-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<!--mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--阿里 FastJson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
<!--阿里 Druid Spring Boot Starter依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.6</version>
</dependency>
<!--代码生成器依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
<scope>test</scope>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Redis 相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- json -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun-repos</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
这是本次项目中所用到的依赖和插件,实际运用中不需要的依赖可自行去掉。
<modelVersion>4.0.0</modelVersion>
<groupId>myBootProject</groupId>
<artifactId>myBootProject</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>myBootProject Maven Webapp</name>
<url>http://maven.apache.org</url>
pom头部 将packageing标签中的war改为jar
3.3 创建Spring Boot启动类 Application
@SpringBootApplication
public class Application extends SpringBootServletInitializer{
/* @Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
builder.sources(Application.class);
return super.configure(builder);
}*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@springBootApplication 注解相当于(默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。由于这些注解一般都是一起使用,spring boot提供了一个统一的注解@SpringBootApplication。
下面分别描述这三个注解的作用
@Configuration:标注当前类为spring的配置文件,通常与@bean注解一起使用,相当于我们以前的xml配置文件。
@EnableAutoConfiguration:自动化配置注解,能够自动配置spring应用上下文,试图猜测和配置你想要的bean类。自动配置被设计用来和“Starters”一起更好的工作,但这两个概念并不直接相关。您可以自由挑选starter依赖项以外的jar包,springboot仍将尽力自动配置您的应用程序。
@ComponentScan:自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。
到目前为止一个简单springboot项目已经完成,启动Application类,便可以运行项目。
四 集成mybatis和Redis
4.1 加入mybatis和redis相关依赖
<!--mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Redis 相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
4.2 创建application.yml配置文件
文件要放在resource的根目录下
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://******:3306/**?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: **
initialize: true
redis:
host: ******
port: 6379
password: ***
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 10000
mybatis:
mapper-locations: classpath*:mapper/*Mapper.xml
type-aliases-package: com.gcx.api.model
yml和properties都可作为配置文件,properties配置是以键值对的形式存储数据,yml则更像是一种JSON格式。yml的层次感更强。具体使用哪种根据个人喜好。
yml注意事项:yml不能使用tab作为空位符,只能用空格键,冒号后面的空格位数要统一,大小写敏感。
本项目将mybatis的mapper.xml放在了resource下的mapper文件下
配置文件中配置了mybati和redis的数据源,以及mybatis的映射路径。项目启动时会加载改配置文件,从而创建对应上下文。
4.3 添加@MapperScan注解
在Application类上添加此注解
@SpringBootApplication
@MapperScan("com.gcx.api.dao")
public class Application extends SpringBootServletInitializer{
/* @Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
builder.sources(Application.class);
return super.configure(builder);
}*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
该注解的作用是将mapper类交由spring管理,在需要的时候创建对应的mapper实例,相当于在每个mapper类上加入@Mapper注解。
4.4 创建redis工具类
package com.gcx.api.common.redis;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.gcx.gcxCommon.model.User;
import com.google.gson.Gson;
/**
*<p>Title:CacheUtil</p>
*<p>Description:redis操作模板</p>
*<p>Company:gcx</p>
*<p>Author:zhanglin</p>
*<p>Date:2017年6月21日</p>
*/
@Component("CacheUtil")
public class CacheUtil {
@Autowired
private StringRedisTemplate redisTemplate;//redis操作模板
public void put(String key, String value) {
if (key==null || "".equals(key)) {
return;
}
redisTemplate.opsForHash().put(key, key, value);
}
public void put(String key, Object value) {
if (key==null || "".equals(key)) {
return;
}
redisTemplate.opsForHash().put(key, key, new Gson().toJson(value));
redisTemplate.expire(key, 6000, TimeUnit.SECONDS);
}
public <T> T get(String key, Class<T> className) {
Object obj = redisTemplate.opsForHash().get(key, key);
if(obj == null){
return null;
}
redisTemplate.expire(key, 6000, TimeUnit.SECONDS);
return new Gson().fromJson(""+obj, className);
}
public String get(String key) {
Object obj = redisTemplate.opsForHash().get(key, key);
if(obj == null){
return null;
}else{
return String.valueOf(obj);
}
}
//============================String操作=================================
public void putString(String key,String value){
redisTemplate.opsForValue().set(key, value, 1000, TimeUnit.SECONDS);
}
public <T> User getString(String key,Class<T> className){
String jsonStr = redisTemplate.opsForValue().get(key);
JSONObject jsonobject = JSONObject.parseObject(jsonStr);
User user= (User)JSONObject.toJavaObject(jsonobject, className);
return user;
}
public void deleteString(String key){
if(key!=null)
redisTemplate.delete(key);
}
}
至此该项目已成功集成mybatis和redis,如需其他扩展,springboot也提供了对应的接口,这里暂不介绍。
五 集成swagger2
5.1 简介
Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
5.2 添加swagger2相关依赖
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
5.3 创建SwaggerConfig类
package com.gcx.api.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
*<p>Title:SwaggerConfig</p>
*<p>Description:Swagger文档 访问地址:http://localhost:端口号/项目名/swagger-ui.html</p>
*<p>Company:gcx</p>
*<p>Author:zhanglin</p>
*<p>Date:2018年2月1日</p>
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.gcx.api.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("swagger2 基于 RestFul的 APIs")
.description("")
.termsOfServiceUrl("")
.contact("Change")
.version("1.0")
.build();
}
}
如上代码所示,通过@Configuration
注解,让Spring来加载该类配置。再通过@EnableSwagger2
注解来启用Swagger2。
再通过createRestApi
函数创建Docket
的Bean之后,apiInfo()
用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。select()
函数返回一个ApiSelectorBuilder
实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore
指定的请求)。
5.4 在controller层和实体类中使用swagger2注解
package com.gcx.api.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gcx.api.common.base.BaseController;
import com.gcx.api.common.exception.ParameterException;
import com.gcx.api.common.util.MyResult;
import com.gcx.api.common.util.StringUtils;
import com.gcx.api.model.UserGroup;
import com.gcx.api.service.UserGroupService;
/**
* @author zhanglin
* @version 创建时间:2018-01-10 12:00:06
*/
@RestController
@Api(value="userGroup",description="群组")
@RequestMapping("/userGroup")
@Validated
class UserGroupController extends BaseController {
@Autowired
UserGroupService userGroupService;
// 查询所有记录 分页默认每页为10条记录,查询全部pageSize传-1
@GetMapping
@ApiOperation(value = "列表",notes="外网调用此接口时,审核状态传3")
MyResult list(@Valid UserGroup record,BindingResult br) throws Exception{
if(br.hasErrors()){
for (ObjectError error : br.getAllErrors()) {
System.out.println(error.getDefaultMessage());
}
return MyResult.ok(br.getAllErrors().get(0).getDefaultMessage());
}
MyResult result=userGroupService.findAllRecords(record);
return result;
}
// 添加记录
@ApiOperation(value = "新增")
@PostMapping
MyResult add(@RequestBody UserGroup record,HttpServletRequest request) throws Exception{
record.setCreateTime(getNowTime());
record.setCreateUser(getUserId(request));
MyResult result = userGroupService.addRecord(record);
return result;
}
// 删除记录 id
@ApiOperation(value = "删除")
@DeleteMapping("/{tid}")
MyResult delete(@PathVariable("tid")String tid) throws Exception{
if(StringUtils.isEmpty(tid))
throw new ParameterException("参数tid不能为空,你传的参数是:"+tid);
MyResult result = userGroupService.delRecord(tid);
return result;
}
// 修改记录 id 要修改的属性
@ApiOperation(value = "修改")
@PutMapping
MyResult update(@RequestBody UserGroup record,HttpServletRequest request) throws Exception{
if(StringUtils.isEmpty(record.getTid()))
throw new ParameterException("参数tid不能为空,你传的参数是:"+record.getTid());
if(record.getAuditStatus()==2){
record.setUpdateTime(getNowTime());
record.setUpdateUser(getUserName(request));
}
MyResult result = userGroupService.updateRecord(record);
return result;
}
// 根据ID查询详情 id
@ApiOperation(value = "查询详情")
@GetMapping("/{tid}")
MyResult get(@PathVariable("tid")String tid) throws Exception{
if(StringUtils.isEmpty(tid))
throw new ParameterException("参数tid不能为空,你传的参数是:"+tid);
MyResult result = userGroupService.findById(tid);
return result;
}
}
@ApiModel(value="UserGroup",description="群组实体类")
public class UserGroup extends BaseEntity {
@ApiModelProperty(value="群组ID")
private String groupId;//群组ID
@NotBlank(message="用户ID不能为空")
@ApiModelProperty(value="用户ID")
private String userId;//用户ID
@NotBlank(message="群名称不能为空")
@ApiModelProperty(value="群名称")
private String groupName;//群名称
}
swagger2常用注解说明
- @Api()用于类;表示标识这个类是swagger的资源
- @ApiOperation()用于方法;
表示一个http请求的操作
- @ApiParam()用于方法,参数,字段说明;
表示对参数的添加元数据(说明或是否必填等)
- @ApiModel()用于类
表示对类进行说明,用于参数用实体类接收
- @ApiModelProperty()用于方法,字段
表示对model属性的说明或者数据操作更改
- @ApiIgnore()用于类,方法,方法参数
表示这个方法或者类被忽略
- @ApiImplicitParam() 用于方法
表示单独的请求参数
- @ApiImplicitParams() 用于方法,包含多个 @ApiImplicitParam
5.5 效果展示
访问路径 http://localhost:8080/swagger-ui.html#/
至此所有整合完成
启动Application类
接口测试
点击Try it out 测试接口
测试结果
接口访问成功。
六 在外部容器中部署springboot项目
6.1 将pom文件中的jar改为war
<modelVersion>4.0.0</modelVersion>
<groupId>myBootProject</groupId>
<artifactId>myBootProject</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>myBootProject Maven Webapp</name>
<url>http://maven.apache.org</url>
6.2 移除springboot自带容器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
6.3 加入servlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
6.4 修改Application类
@SpringBootApplication
@MapperScan("com.gcx.api.dao")
public class Application extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
builder.sources(Application.class);
return super.configure(builder);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在Application类中加入configure方法
至此便可将项目部署到外部容器中
外部容器访问接口时要加上项目名称
若需要完整项目请加群 499950895