yaml 语法参考: https://www.jianshu.com/p/97222440cd08
在线properties转yaml工具: http://www.toyaml.com/index.html
server:
port: 8181
spring:
application:
name: multipart-environment
profiles:
active: dev # 指定启动环境
# 开发环境
---
spring:
profiles: dev
test:
env: dev
# 测试环境
---
spring:
profiles: test
test:
env: test
# 生产环境
---
spring:
profiles: prod
test:
env: prod
如果你想要自己创建一个starter,那么基本上包含以下几步:
新建一个Maven项目,设置 pom.xml 文件
<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.0modelVersion>
<artifactId>http-starterartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-startersartifactId>
<version>2.2.2.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.10version>
dependency>
dependencies>
project>
创建proterties类来保存配置信息
@ConfigurationProperties(prefix = "http")
@Setter
@Getter
public class HttpProperties {
// 如果配置文件中配置了http.url属性,则该默认属性会被覆盖
private String url = "http://www.baidu.com/";
}
创建业务类
@Setter
@Getter
public class HttpClient {
private String url;
// 根据url获取网页数据
public String getHtml() {
try {
URL url = new URL(this.url);
URLConnection urlConnection = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "error";
}
}
创建AutoConfiguration
@Configuration
@EnableConfigurationProperties(HttpProperties.class)
public class HttpAutoConfiguration {
@Resource
private HttpProperties properties;
@Bean
@ConditionalOnMissingBean
public HttpClient init() {
HttpClient client = new HttpClient();
String url = properties.getUrl();
client.setUrl(url);
return client;
}
}
在 resources 文件夹下新建目录 META-INF,在目录中新建 spring.factories 文件,并且在 spring.factories 中配置AutoConfiguration:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.nosuchfield.httpstarter.HttpAutoConfiguration
测试
@Component
public class RunIt {
@Resource
private HttpClient httpClient;
public void hello() {
System.out.println(httpClient.getHtml());
}
}
<packaging>warpackaging>
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
在pom.xml文件中加入如下依赖
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
dependencies>
配置在web.xml中,依赖于servlet容器。
优点:
在实现上Filter是基于函数回调,可以对几乎所有请求进行过滤
缺点:
一个过滤器实例只能在容器初始化时调用一次 . 当容器第一次加载该过滤器时,init() 方法将被调用
使用场景:
比如设置编码、过滤敏感词汇、禁止浏览器缓存所有动态页面、实现用户自动登陆、实现URL级别的权限认证等等 ,具体案例参考Filter(过滤器)常见应用
传统的JavaEE项目开发filter的主要2个步骤
它使用户可以改变一个 request和修改一个response,Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response,换种说法,filter其实是一个 “servlet chaining” (servlet 链)。
一个Filter包括:
1)在servlet被调用之前截获
2)在servlet被调用之前检查servlet request
3)根据需要修改request头和request数据
4)根据需要修改response头和response数据
5)在servlet被调用之后截获
public class GlobalFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestURI = request.getRequestURI();
System.out.println(requestURI);
filterChain.doFilter(request, servletResponse);
}
@Override
public void destroy() {
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistration(){
// 新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加自定义过滤器
registration.setFilter(globalFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
//设置过滤器顺序
registration.setOrder(1);
return registration;
}
@Bean
public GlobalFilter globalFilter(){
return new GlobalFilter();
}
}
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestURI = request.getRequestURI();
if(requestURI.contains("my")){
System.out.println("成功啦, 请求URI是:" + requestURI);
}
filterChain.doFilter(request, servletResponse);
}
@Override
public void destroy() {
System.out.println("destroy...");
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Interceptor依赖于web框架,我们经常在Spring MVC中用到该配置,在这个场景下Interceptor 就依赖于SpringMVC框架。Interceptor 基于Java的反射机制,属于AOP的一种运用。
优点:
由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。
缺点:
只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
多个拦截器的执行顺序是按照责任链模式的规则,对于处理器前方法采用先注册先执行,而处理器后方法和完成方法则是先注册后执行的规则。
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyInterceptor implements HandlerInterceptor {
/**
* 进入controller层之前拦截请求
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("getContextPath:" + request.getContextPath());
System.out.println("getServletPath:" + request.getServletPath());
System.out.println("getRequestURI:" + request.getRequestURI());
System.out.println("getRequestURL:" + request.getRequestURL());
System.out.println("getRealPath:" + request.getSession().getServletContext().getRealPath("image"));
return true;
}
/**
* 处理请求完成后视图渲染之前的处理操作
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
/**
* 视图渲染之后的操作
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}
拦截器注册
可以用来注册拦截器的类和接口:
import com.fxbin.demo.interceptor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截路径和排除拦截路径
registry.addInterceptor(myInterceptor()).addPathPatterns("/**").excludePathPatterns("/test");
}
}
Filter的执行顺序在Interceptor之前 。拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,Interceptor都能做,而且可以在请求前,请求后执行,比较灵活。
参考:浏览器同源政策及其规避方法
浏览器安全的基石是"同源政策"(same-origin policy),现代浏览器出于安全的考虑,在http/https请求时必须遵守同源策略,否则跨域的http/https 请求,默认情况下是被禁止的,协议、域名、端口但凡有一个不同都会造成跨域问题。如果发生跨域,则浏览器中每次请求的session都是一个新的,即sessionId肯定不相同。
所谓"同源"指的是"三个相同"
非同源,共有三种行为受到限制
前端解决方案
后来 HTML5 支持了 CORS 协议。CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。它通过服务器增加一个特殊的 Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持 CORS、并且判断 Origin 通过的话,就会允许 XMLHttpRequest 发起跨域请求。
前端使用了 CORS 协议,就需要后端设置支持非同源的请求,对于SpringBoot 对于CORS 同样有着良好的支持。
浏览器和session
集群环境下Session管理思路
小结
三种配置方式:
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.addExposedHeader("*");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}
@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("*");
}
}
@RequestMapping("/hello")
@CrossOrigin("http://localhost:8080")
public String hello( ){
return "Hello World";
}
在pom.xml文件中加入如下依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
@RunWith(SpringRunner.class)
@SpringBootTest(classes={
Application.class})// 指定启动类
public class ApplicationTests {
@Test
public void testOne(){
System.out.println("test hello one");
}
@Before
public void testBefore(){
System.out.println("before");
}
@After
public void testAfter(){
System.out.println("after");
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class MockMvcTest {
//注入一个web应用环境(容器)
@Resource
private WebApplicationContext webApplicationContext;
//mvc环境对象
private MockMvc mockMvc;
@Before
public void init(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
@Test
public void findObject() throws Exception {
String str = mockMvc.perform(MockMvcRequestBuilders.get("/1/2")
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(2))
.andReturn().getResponse().getContentAsString();
System.out.println(str);
}
perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;
andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;
测试过程如下:
1、准备测试环境
2、通过MockMvc执行请求
3.1、添加验证断言
3.2、添加结果处理器
3.3、得到MvcResult进行自定义断言/进行下一步的异步请求
4、卸载测试环境
SpringBoot 默认提供了两种机制:
通过 @ControllerAdvice、@RestControllerAdvice、@ExceptionHandler 注解全局异常自定义响应类。
public enum ResultCode {
SUCCESS(200),//成功
FAIL(400),//失败
UNAUTHORIZED(401),//未认证(签名错误)
NOT_FOUND(404),//接口不存在
INTERNAL_SERVER_ERROR(500);//服务器内部错误
private final int code;
ResultCode(int code) {
this.code = code;
}
public int code() {
return code;
}
}
定义响应类
public class Result {
/**
* 状态响应码
*/
private int code;
/**
* 响应结果 成功/失败
*/
private boolean success;
/**
* 响应信息
*/
private String message;
/**
* 响应数据
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private Object data;
public Result setCode(ResultCode resultCode) {
this.code = resultCode.code();
return this;
}
public int getCode() {
return code;
}
public boolean isSuccess() {
return success;
}
public Result setSuccess(boolean success) {
this.success = success;
return this;
}
public String getMessage() {
return message;
}
public Result setMessage(String message) {
this.message = message;
return this;
}
public Object getData() {
return data;
}
public Result setData(Object data) {
this.data = data;
return this;
}
}
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
public static Result genSuccessResult() {
return new Result()
.setCode(ResultCode.SUCCESS)
.setSuccess(true)
.setMessage(DEFAULT_SUCCESS_MESSAGE);
}
public static Result genSuccessResult(Object data) {
return new Result()
.setCode(ResultCode.SUCCESS)
.setSuccess(true)
.setMessage(DEFAULT_SUCCESS_MESSAGE)
.setData(data);
}
public static Result genFailResult(String message) {
return new Result()
.setCode(ResultCode.FAIL)
.setSuccess(false)
.setMessage(message);
}
}
import com.fxbin123.dto.Result;
import com.fxbin123.dto.ResultGenerator;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
@RestControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(Exception.class)
public Result jsonErrorHandler(HttpServletRequest req, Exception e){
return ResultGenerator.genFailResult(e.getMessage());
}
}
thymeleaf
依赖<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorator="layout">
<head>
<title>Spring Boot 自定义异常页面title>
<script type="text/javascript">
script>
head>
<body>
<div layout:fragment="content" th:remove="tag">
<div id="navbar">
<h1>系统异常统一处理h1>
<h3 th:text="'错误信息:'+${msg}">h3>
<h3 th:text="'请求地址:'+${url}">h3>
<h2>Debugh2>
<a th:href="@{
'https://www.google.com/webhp?hl=zh-CN#safe=strict&hl=zh-CN&q='+${msg}}"
class="btn btn-primary btn-lg" target="_blank" id="Google">Googlea>
<a th:href="@{
'https://www.baidu.com/s?wd='+${msg}}" class="btn btn-info btn-lg" target="_blank" id="Baidu">Baidua>
<a th:href="@{
'http://stackoverflow.com/search?q='+${msg}}"
class="btn btn-default btn-lg" target="_blank" id="StackOverFlow">StackOverFlowa>
<h2>异常堆栈跟踪日志StackTraceh2>
<div th:each="line:${stackTrace}">
<div th:text="${line}">div>
div>
div>
div>
<div layout:fragment="js" th:remove="tag">
div>
body>
html>
做错误页面异常处理 返回 ModelAndView
@ExceptionHandler(Exception.class)
public Object handleException(Exception e){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", e.getMessage());
modelAndView.addObject("url", req.getRequestURL());
modelAndView.addObject("stackTrace", e.getStackTrace());
modelAndView.setViewName("error");
return modelAndView;
}
官网:https://freemarker.apache.org/
在线手册:http://freemarker.foofun.cn/
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
spring:
application:
name: freemarker
freemarker:
# 禁用模板缓存
cache: false
# 编码格式
charset: UTF-8
# freemarker模板后缀 默认是 .ftl
suffix: .html
# 是否为此技术启用MVC视图分辨率。
enabled: true
# Content-Type值
content-type: text/html
# #模板加载路径 按需配置 ,默认路径是 classpath:/templates/
template-loader-path: classpath:/templates/
<html lang="en">
<head>
<meta charset="UTF-8">
<title>indextitle>
head>
<body>
Hello ${content}
body>
html>
@Controller
public class FreemarkerController {
@RequestMapping("/index")
public String index(Model model){
model.addAttribute("content", "Freemarker");
return "index";
}
}
官网:https://www.thymeleaf.org/
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
server:
port: 8081
spring:
application:
name: thymeleaf
thymeleaf:
# 是否启用模板缓存。
cache: true
# 是否检查模板位置是否存在。
check-template: true
# 是否为Web框架启用Thymeleaf视图分辨率。
enabled: true
# 编码格式, 默认UTF-8
encoding: UTF-8
# 应用于模板的模板模式。另请参阅Thymeleaf的TemplateMode枚举。
mode: HTML
# 后缀 默认 .html
suffix: .html
# 模板文件存放位置 , 默认 classpath:/templates/
prefix: classpath:/templates/
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1 th:text="${content}">h1>
body>
html>
@Controller
public class ThymeleafController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("content", "Hello Thymeleaf");
return "index";
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.2.9version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.9version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
spring:
application:
name: mybatis-curd
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/test?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&autoReconnect=true
continue-on-error: true
sql-script-encoding: UTF-8
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
# 间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
# 一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
use-global-data-source-stat: true
filters: stat,wall,log4j2
mybatis:
type-aliases-package: com.yanggle.mybaits.*
configuration:
map-underscore-to-camel-case: true
# 打印sql, 方便调试
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
use-generated-keys: true
default-statement-timeout: 60
default-fetch-size: 100
import lombok.Data;
import java.util.Date;
@Data
public class User {
// 主键ID
private Integer id;
// 用户名
private String username;
// 密码
private String password;
// 创建时间
private Date gmtCreate;
// 修改时间
private Date gmtModified;
}
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class MyBatisConfig {
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
// 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用
p.setProperty("offsetAsPageNum","true");
//设置为true时,使用RowBounds分页会进行count查询
p.setProperty("rowBoundsWithCount","true");
p.setProperty("reasonable","true");
pageHelper.setProperties(p);
return pageHelper;
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fxbin.mybatis.bean.User;
import com.fxbin.mybatis.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/listAll")
public Object listAll(@RequestParam(value = "page",defaultValue = "1")int page,
@RequestParam(value = "size",defaultValue = "10")int size){
return userService.listAll(page, size);
}
@RequestMapping("/insert")
public int insert (User user){
return userService.insert(user);
}
@RequestMapping("/remove")
public int remove(Integer userId){
return userService.remove(userId);
}
@RequestMapping("/update")
public int update(User user){
return userService.update(user);
}
}
import com.fxbin.mybatis.bean.User;
import java.util.List;
public interface UserService {
Object listAll(int page, int size);
int insert(User user);
int remove(Integer userId);
int update(User user);
}
import com.fxbin.mybatis.bean.User;
import com.fxbin.mybatis.mapper.UserMapper;
import com.fxbin.mybatis.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public Object listAll(int page, int size) {
PageHelper.startPage(page, size);
List<User> userList = userMapper.listAll();
PageInfo<User> pageInfo = new PageInfo<>(userList);
return pageInfo;
}
@Override
public int insert(User user) {
return userMapper.insert(user);
}
@Override
public int remove(Integer userId) {
return userMapper.remove(userId);
}
@Override
public int update(User user) {
return userMapper.update(user);
}
}
import com.fxbin.mybatis.bean.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
@Select({
"select * from user"
})
List<User> listAll();
@Insert({
"insert into user(`username`, `password`) values(#{username}, #{password})"
})
int insert(User user);
@Delete({
"delete from user where id = #{userId}"
})
int remove(Integer userId);
@Update({
"update user set username = #{username}, password = #{password} where id = #{id}"
})
int update(User user);
}
官网: https://prometheus.io/
下载地址: https://prometheus.io/download/
官方文档: https://prometheus.io/docs/prometheus/latest/getting_started/
Prometheus是一套开源的监控&报警&时间序列数据库的组合,基于应用的metrics来进行监控的开源工具 。
更多信息请参考官网介绍: https://prometheus.io/docs/introduction/overview/
#下载
[root@artisan ~]# wget http://cactifans.hi-www.com/prometheus/prometheus-2.1.0.linux-amd64.tar.gz
#解压
[root@artisan ~]# tar -xvzf prometheus-2.1.0.linux-amd64.tar.gz
#创建软连接
[root@artisan ~]# ln -s prometheus-2.1.0.linux-amd64 prometheus
#后台运行 &
[root@artisan prometheus]# ./prometheus --config.file=prometheus.yml &
#SpringBoot应用配置
job_name: 'app-prometheus-grafana'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
static_configs:
targets: ['192.168.0.1:8080']
官网:https://grafana.com/
下载地址: https://grafana.com/grafana/download
入门:http://docs.grafana.org/guides/getting_started/
Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。它主要有以下六大特点:
# 下载
[root@artisan ~]# wget http://cactifans.hi-www.com/grafana/grafana-5.4.2-1.x86_64.rpm
# yum本地安装
[root@artisan ~]# yum localinstall grafana-5.4.2-1.x86_64.rpm
# 启动
[root@artisan ~]# systemctl start grafana-server
# 设置为开机启动
[root@artisan ~]# systemctl enable grafana-server
# 查看进程
[root@artisan ~]# ps -ef|grep grafana-server |grep -v grep
RabbitMQ名词
将包名改为与其被测试代码分支一样的路径