@@ -1,106 +0,0 @@ | |||||
# spring-boot-demo-actuator | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、spring-boot-starter-actuator | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-actuator</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-actuator</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-actuator</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-actuator</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
# actuator 配置 | |||||
management: | |||||
security: | |||||
# 关闭 actuator 的身份验证 | |||||
enabled: false | |||||
# 配置 actuator 的访问路径前缀 | |||||
context-path: /sys | |||||
# actuator暴露接口使用的端口,为了和api接口使用的端口进行分离 | |||||
port: 1111 | |||||
``` | |||||
### actuator 提供的端点信息 | |||||
| 端点 | 描述 | HTTP 方法 | | |||||
| ----------- | ---------------------------------------- | ------- | | |||||
| autoconfig | 显示自动配置的信息 | GET | | |||||
| beans | 显示应用程序上下文所有的Spring bean | GET | | |||||
| configprops | 显示所有 `@ConfigurationProperties` 的配置属性列表 | GET | | |||||
| dump | 显示线程活动的快照 | GET | | |||||
| env | 显示应用的环境变量 | GET | | |||||
| health | 显示应用程序的健康指标,这些值由HealthIndicator的实现类提供。常见取值:`UP` / `DOWN` / `UNKNOWN` / `OUT_OF_SERVICE` | GET | | |||||
| info | 显示应用的信息,可使用 `info.*` 属性自定义info端点公开的数据 | GET | | |||||
| mappings | 显示所有的URL路径 | GET | | |||||
| metrics | 显示应用的度量标准信息 | GET | | |||||
| shutdown | 关闭应用(默认情况下不启用,如需启用,需设置`endpoints.shutdown.enabled=true`) | POST | | |||||
| trace | 显示跟踪信息(默认情况下为最近100个HTTP请求) | GET | | |||||
### actuator 的访问权限 | |||||
#### 方法一:(本 demo 中使用的是这种) | |||||
```yaml | |||||
management: | |||||
security: | |||||
enabled: false | |||||
``` | |||||
#### 方法二: | |||||
pom.xml 中添加以下 `spring-boot-starter-security` 依赖: | |||||
```xml | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-security</artifactId> | |||||
</dependency> | |||||
``` | |||||
并在 `application.yml` 文件中设置访问的密码 | |||||
```yaml | |||||
security: | |||||
basic: | |||||
enabled: true | |||||
user: | |||||
name: user | |||||
password: 123 | |||||
``` | |||||
如果不设置,则用户名是 user,密码是一个随机值,在启动时会在控制台打印。 |
@@ -1,31 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-actuator</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-actuator</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-actuator</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-actuator</finalName> | |||||
</build> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemoactuator; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoActuatorApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoActuatorApplication.class, args); | |||||
} | |||||
} |
@@ -1,12 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
# actuator 配置 | |||||
management: | |||||
security: | |||||
# 关闭 actuator 的身份验证 | |||||
enabled: false | |||||
# 配置 actuator 的访问路径前缀 | |||||
context-path: /sys | |||||
# actuator暴露接口使用的端口,为了和api接口使用的端口进行分离 | |||||
port: 1111 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoactuator; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoActuatorApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,103 +0,0 @@ | |||||
# spring-boot-demo-admin | |||||
依赖[spring-boot-demo-parent](../spring-boot-demo-parent)、服务端依赖 `spring-boot-demo-admin` 和 `spring-boot-admin-server-ui`、客户端依赖 `spring-boot-admin-starter-client` | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-admin</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-admin</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<admin.server.version>1.5.2</admin.server.version> | |||||
<admin.server.ui.version>1.5.2</admin.server.ui.version> | |||||
<admin.client.version>1.5.2</admin.client.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-server</artifactId> | |||||
<version>${admin.server.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-server-ui</artifactId> | |||||
<version>${admin.server.ui.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-starter-client</artifactId> | |||||
<version>${admin.client.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-admin</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
application: | |||||
# 可视化管控台展示的监控项目名,不设置,会使用自动生成的名字 | |||||
name: Spring Boot Admin | |||||
boot: | |||||
admin: | |||||
# 可视化管控台界面的 context-path | |||||
context-path: /spa | |||||
url: http://localhost:${server.port}/${server.context-path} | |||||
jackson: | |||||
serialization: true | |||||
# 去除权限校验 | |||||
endpoints: | |||||
sensitive: false | |||||
``` | |||||
### SpringBootDemoAdminApplication.java | |||||
```java | |||||
@SpringBootApplication | |||||
@EnableAdminServer // 开启管控台 | |||||
@RestController | |||||
public class SpringBootDemoAdminApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoAdminApplication.class, args); | |||||
} | |||||
@GetMapping("/") | |||||
public Map<String, Object> index() { | |||||
ConcurrentMap<String, Object> ret = Maps.newConcurrentMap(); | |||||
ret.put("msg", "Hello Spring Boot Admin"); | |||||
return ret; | |||||
} | |||||
} | |||||
``` | |||||
### 访问 | |||||
http://localhost:8080/demo/spa 即可查看管控台主页,点击项目的 `Detail` 即可查看详细信息,但是比起 `actuator` 提供的端点监控,看起来确实美观不少,但是都各有优缺点。 |
@@ -1,48 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-admin</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-admin</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<admin.server.version>1.5.2</admin.server.version> | |||||
<admin.server.ui.version>1.5.2</admin.server.ui.version> | |||||
<admin.client.version>1.5.2</admin.client.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-server</artifactId> | |||||
<version>${admin.server.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-server-ui</artifactId> | |||||
<version>${admin.server.ui.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>de.codecentric</groupId> | |||||
<artifactId>spring-boot-admin-starter-client</artifactId> | |||||
<version>${admin.client.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-admin</finalName> | |||||
</build> | |||||
</project> |
@@ -1,28 +0,0 @@ | |||||
package com.xkcoding.springbootdemoadmin; | |||||
import com.google.common.collect.Maps; | |||||
import de.codecentric.boot.admin.config.EnableAdminServer; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.util.Map; | |||||
import java.util.concurrent.ConcurrentMap; | |||||
@SpringBootApplication | |||||
@EnableAdminServer // 开启管控台 | |||||
@RestController | |||||
public class SpringBootDemoAdminApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoAdminApplication.class, args); | |||||
} | |||||
@GetMapping("/") | |||||
public Map<String, Object> index() { | |||||
ConcurrentMap<String, Object> ret = Maps.newConcurrentMap(); | |||||
ret.put("msg", "Hello Spring Boot Admin"); | |||||
return ret; | |||||
} | |||||
} |
@@ -1,17 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
application: | |||||
# 可视化管控台展示的监控项目名,不设置,会使用自动生成的名字 | |||||
name: Spring Boot Admin | |||||
boot: | |||||
admin: | |||||
# 可视化管控台界面的 context-path | |||||
context-path: /spa | |||||
url: http://localhost:${server.port}/${server.context-path} | |||||
jackson: | |||||
serialization: true | |||||
# 去除权限校验 | |||||
endpoints: | |||||
sensitive: false |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoadmin; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoAdminApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,168 +0,0 @@ | |||||
# spring-boot-demo-aoplog | |||||
依赖[spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-aop` | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-aoplog</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-aoplog</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<useragent.version>1.20</useragent.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-aop</artifactId> | |||||
</dependency> | |||||
<!--UserAgent工具类--> | |||||
<dependency> | |||||
<groupId>eu.bitwalker</groupId> | |||||
<artifactId>UserAgentUtils</artifactId> | |||||
<version>${useragent.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-aoplog</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### AopLog.java | |||||
```java | |||||
/** | |||||
* aop 切面记录请求日志 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoaoplog.aspectj | |||||
* @description:aop 切面记录请求日志 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 上午9:43 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Aspect | |||||
@Component | |||||
@Slf4j | |||||
public class AopLog { | |||||
private static final String START_TIME = "start-request"; | |||||
@Pointcut("execution(public * com.xkcoding.springbootdemoaoplog.controller.*Controller.*(..))") | |||||
public void log() { | |||||
} | |||||
@Before("log()") | |||||
public void beforeLog(JoinPoint joinPoint) { | |||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); | |||||
HttpServletRequest request = attributes.getRequest(); | |||||
log.info("【请求 URL】:{}", request.getRequestURL()); | |||||
log.info("【请求 IP】:{}", request.getRemoteAddr()); | |||||
log.info("【请求类名】:{},【请求方法名】:{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName()); | |||||
Map parameterMap = request.getParameterMap(); | |||||
log.info("【请求参数】:{},", JsonMapper.obj2Str(parameterMap)); | |||||
Long start = System.currentTimeMillis(); | |||||
request.setAttribute(START_TIME, start); | |||||
} | |||||
@Around("log()") | |||||
public Object arroundLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { | |||||
Object result = proceedingJoinPoint.proceed(); | |||||
log.info("【返回值】:{}", JsonMapper.obj2Str(result)); | |||||
return result; | |||||
} | |||||
@AfterReturning("log()") | |||||
public void afterReturning(JoinPoint joinPoint) { | |||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); | |||||
HttpServletRequest request = attributes.getRequest(); | |||||
Long start = (Long) request.getAttribute(START_TIME); | |||||
Long end = System.currentTimeMillis(); | |||||
log.info("【请求耗时】:{}毫秒", end - start); | |||||
String header = request.getHeader("User-Agent"); | |||||
UserAgent userAgent = UserAgent.parseUserAgentString(header); | |||||
log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header); | |||||
} | |||||
} | |||||
``` | |||||
### JsonMapper.java | |||||
```java | |||||
/** | |||||
* Json 转化工具类 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoaoplog.util | |||||
* @description:Json 转化工具类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 上午9:36 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Slf4j | |||||
public class JsonMapper { | |||||
private static ObjectMapper objectMapper = new ObjectMapper(); | |||||
/** | |||||
* 对象转 json 字符串 | |||||
* | |||||
* @param src 元对象 | |||||
* @param <T> 类型 | |||||
* @return json 字符串 | |||||
*/ | |||||
public static <T> String obj2Str(T src) { | |||||
if (src == null) { | |||||
return null; | |||||
} | |||||
try { | |||||
return src instanceof String ? (String) src : objectMapper.writeValueAsString(src); | |||||
} catch (IOException e) { | |||||
log.error("【JSON 转换:对象 --> 字符串】,异常堆栈:{}", e); | |||||
return null; | |||||
} | |||||
} | |||||
/** | |||||
* json 字符串转化为对象 | |||||
* | |||||
* @param src 源 json 字符串 | |||||
* @param typeReference 转化后的类型 | |||||
* @param <T> 类型 | |||||
* @return 返回转化后的对象 | |||||
*/ | |||||
public static <T> T str2Obj(String src, TypeReference<T> typeReference) { | |||||
if (src == null || typeReference == null) { | |||||
return null; | |||||
} | |||||
try { | |||||
return (T) (typeReference.getType().equals(String.class) ? src : objectMapper.readValue(src, typeReference)); | |||||
} catch (Exception e) { | |||||
log.error("【JSON 转换:字符串 --> 对象】,异常堆栈:{}", e); | |||||
return null; | |||||
} | |||||
} | |||||
} | |||||
``` | |||||
@@ -1,41 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-aoplog</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-aoplog</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<useragent.version>1.20</useragent.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-aop</artifactId> | |||||
</dependency> | |||||
<!--UserAgent工具类--> | |||||
<dependency> | |||||
<groupId>eu.bitwalker</groupId> | |||||
<artifactId>UserAgentUtils</artifactId> | |||||
<version>${useragent.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-aoplog</finalName> | |||||
</build> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemoaoplog; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoAoplogApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoAoplogApplication.class, args); | |||||
} | |||||
} |
@@ -1,69 +0,0 @@ | |||||
package com.xkcoding.springbootdemoaoplog.aspectj; | |||||
import com.xkcoding.springbootdemoaoplog.util.JsonMapper; | |||||
import eu.bitwalker.useragentutils.UserAgent; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.aspectj.lang.JoinPoint; | |||||
import org.aspectj.lang.ProceedingJoinPoint; | |||||
import org.aspectj.lang.annotation.*; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.web.context.request.RequestContextHolder; | |||||
import org.springframework.web.context.request.ServletRequestAttributes; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import java.util.Map; | |||||
/** | |||||
* aop 切面记录请求日志 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoaoplog.aspectj | |||||
* @description:aop 切面记录请求日志 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 上午9:43 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Aspect | |||||
@Component | |||||
@Slf4j | |||||
public class AopLog { | |||||
private static final String START_TIME = "start-request"; | |||||
@Pointcut("execution(public * com.xkcoding.springbootdemoaoplog.controller.*Controller.*(..))") | |||||
public void log() { | |||||
} | |||||
@Before("log()") | |||||
public void beforeLog(JoinPoint joinPoint) { | |||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); | |||||
HttpServletRequest request = attributes.getRequest(); | |||||
log.info("【请求 URL】:{}", request.getRequestURL()); | |||||
log.info("【请求 IP】:{}", request.getRemoteAddr()); | |||||
log.info("【请求类名】:{},【请求方法名】:{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName()); | |||||
Map parameterMap = request.getParameterMap(); | |||||
log.info("【请求参数】:{},", JsonMapper.obj2Str(parameterMap)); | |||||
Long start = System.currentTimeMillis(); | |||||
request.setAttribute(START_TIME, start); | |||||
} | |||||
@Around("log()") | |||||
public Object arroundLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { | |||||
Object result = proceedingJoinPoint.proceed(); | |||||
log.info("【返回值】:{}", JsonMapper.obj2Str(result)); | |||||
return result; | |||||
} | |||||
@AfterReturning("log()") | |||||
public void afterReturning(JoinPoint joinPoint) { | |||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); | |||||
HttpServletRequest request = attributes.getRequest(); | |||||
Long start = (Long) request.getAttribute(START_TIME); | |||||
Long end = System.currentTimeMillis(); | |||||
log.info("【请求耗时】:{}毫秒", end - start); | |||||
String header = request.getHeader("User-Agent"); | |||||
UserAgent userAgent = UserAgent.parseUserAgentString(header); | |||||
log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header); | |||||
} | |||||
} |
@@ -1,38 +0,0 @@ | |||||
package com.xkcoding.springbootdemoaoplog.controller; | |||||
import com.google.common.collect.Maps; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.util.Map; | |||||
import java.util.concurrent.ConcurrentMap; | |||||
/** | |||||
* IndexController | |||||
* | |||||
* @package: com.xkcoding.springbootdemoaoplog.controller | |||||
* @description:IndexController | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 上午9:36 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Slf4j | |||||
@RestController | |||||
public class IndexController { | |||||
@GetMapping({"", ""}) | |||||
public String index() { | |||||
return "index"; | |||||
} | |||||
@GetMapping({"/test"}) | |||||
public Map test(@RequestParam String name) { | |||||
ConcurrentMap<String, Object> ret = Maps.newConcurrentMap(); | |||||
ret.put("name", name); | |||||
return ret; | |||||
} | |||||
} |
@@ -1,62 +0,0 @@ | |||||
package com.xkcoding.springbootdemoaoplog.util; | |||||
import com.fasterxml.jackson.core.type.TypeReference; | |||||
import com.fasterxml.jackson.databind.ObjectMapper; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import java.io.IOException; | |||||
/** | |||||
* Json 转化工具类 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoaoplog.util | |||||
* @description:Json 转化工具类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 上午9:36 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Slf4j | |||||
public class JsonMapper { | |||||
private static ObjectMapper objectMapper = new ObjectMapper(); | |||||
/** | |||||
* 对象转 json 字符串 | |||||
* | |||||
* @param src 元对象 | |||||
* @param <T> 类型 | |||||
* @return json 字符串 | |||||
*/ | |||||
public static <T> String obj2Str(T src) { | |||||
if (src == null) { | |||||
return null; | |||||
} | |||||
try { | |||||
return src instanceof String ? (String) src : objectMapper.writeValueAsString(src); | |||||
} catch (IOException e) { | |||||
log.error("【JSON 转换:对象 --> 字符串】,异常堆栈:{}", e); | |||||
return null; | |||||
} | |||||
} | |||||
/** | |||||
* json 字符串转化为对象 | |||||
* | |||||
* @param src 源 json 字符串 | |||||
* @param typeReference 转化后的类型 | |||||
* @param <T> 类型 | |||||
* @return 返回转化后的对象 | |||||
*/ | |||||
public static <T> T str2Obj(String src, TypeReference<T> typeReference) { | |||||
if (src == null || typeReference == null) { | |||||
return null; | |||||
} | |||||
try { | |||||
return (T) (typeReference.getType().equals(String.class) ? src : objectMapper.readValue(src, typeReference)); | |||||
} catch (Exception e) { | |||||
log.error("【JSON 转换:字符串 --> 对象】,异常堆栈:{}", e); | |||||
return null; | |||||
} | |||||
} | |||||
} |
@@ -1,3 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoaoplog; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoAoplogApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,172 +0,0 @@ | |||||
# spring-boot-demo-cache-redis | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-data-redis` | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-cache-redis</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-cache-redis</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-data-redis</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-cache-redis</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
redis: | |||||
host: localhost | |||||
port: 6379 | |||||
``` | |||||
### SpringBootDemoCacheRedisApplication.java (开启使用缓存注解) | |||||
```java | |||||
@SpringBootApplication | |||||
@EnableCaching | |||||
public class SpringBootDemoCacheRedisApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args); | |||||
} | |||||
} | |||||
``` | |||||
### User.java (一定要序列化!) | |||||
```java | |||||
@Data | |||||
public class User implements Serializable { | |||||
private static final long serialVersionUID = 1442134563392432775L; | |||||
private Long id; | |||||
private String name; | |||||
private Date birthDay; | |||||
} | |||||
``` | |||||
### UserController.java | |||||
```java | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称 | |||||
public class UserController { | |||||
@Autowired | |||||
private UserService userService; | |||||
@GetMapping({"", "/"}) | |||||
@Cacheable | |||||
public List<User> index() { | |||||
return userService.find(); | |||||
} | |||||
@GetMapping("/find/{id}") | |||||
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法 | |||||
public User find(@PathVariable Long id) { | |||||
return userService.find(id); | |||||
} | |||||
@GetMapping("/find") | |||||
@Cacheable(key = "#name", condition = "#name != null") | |||||
public User find(@RequestParam String name) { | |||||
return userService.find(name); | |||||
} | |||||
@GetMapping("/save") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存 | |||||
public User save() { | |||||
return userService.save(); | |||||
} | |||||
@GetMapping("/update/{id}") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||||
public User update(@PathVariable Long id) { | |||||
return userService.update(id); | |||||
} | |||||
@GetMapping("/delete/{id}") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||||
public String delete(@PathVariable Long id) { | |||||
User user = userService.delete(id); | |||||
if (user == null) { | |||||
return "用户不存在"; | |||||
} else { | |||||
return user.getName() + "删除成功"; | |||||
} | |||||
} | |||||
} | |||||
``` | |||||
### 其余 Service、Dao 代码(采用 List 存储,只为了演示启用 cache 后,是否仍会进入对应的 method) | |||||
详情请参见本demo。 | |||||
### 缓存 @Annotation 详解 | |||||
#### @CacheConfig | |||||
用于统一配置缓存的基本信息 | |||||
#### @Cacheable | |||||
将返回的结果缓存,该注解里的参数如下 | |||||
| 参数 | 作用 | 示例 | | |||||
| --------- | ---------------------------------------- | ---------------------------------------- | | |||||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} | | |||||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) | | |||||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) | | |||||
#### @CacheEvict | |||||
能够根据一定的条件对缓存进行清空,该注解里的参数如下 | |||||
| 参数 | 作用 | 示例 | | |||||
| ---------------- | ---------------------------------------- | ---------------------------------------- | | |||||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} | | |||||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@CachEvict(value=”testcache”,key=”#userName”) | | |||||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如:@CachEvict(value=”testcache”,condition=”#userName.length()>2”) | | |||||
| allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如:@CachEvict(value=”testcache”,allEntries=true) | | |||||
| beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如:@CachEvict(value=”testcache”,beforeInvocation=true) | | |||||
#### @CachePut | |||||
能够根据方法的请求参数对其结果进行缓存,和 `@Cacheable` 不同的是,它每次都会触发真实方法的调用 | |||||
| 参数 | 作用 | 示例 | | |||||
| --------- | ---------------------------------------- | ---------------------------------------- | | |||||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} | | |||||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) | | |||||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) | |
@@ -1,31 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-cache-redis</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-cache-redis</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-data-redis</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-cache-redis</finalName> | |||||
</build> | |||||
</project> |
@@ -1,14 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
import org.springframework.cache.annotation.EnableCaching; | |||||
@SpringBootApplication | |||||
@EnableCaching | |||||
public class SpringBootDemoCacheRedisApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args); | |||||
} | |||||
} |
@@ -1,61 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis.controller; | |||||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||||
import com.xkcoding.springbootdemocacheredis.service.UserService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.cache.annotation.CacheConfig; | |||||
import org.springframework.cache.annotation.CacheEvict; | |||||
import org.springframework.cache.annotation.Cacheable; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import java.util.List; | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称 | |||||
public class UserController { | |||||
@Autowired | |||||
private UserService userService; | |||||
@GetMapping({"", "/"}) | |||||
@Cacheable | |||||
public List<User> index() { | |||||
return userService.find(); | |||||
} | |||||
@GetMapping("/find/{id}") | |||||
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法 | |||||
public User find(@PathVariable Long id) { | |||||
return userService.find(id); | |||||
} | |||||
@GetMapping("/find") | |||||
@Cacheable(key = "#name", condition = "#name != null") | |||||
public User find(@RequestParam String name) { | |||||
return userService.find(name); | |||||
} | |||||
@GetMapping("/save") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存 | |||||
public User save() { | |||||
return userService.save(); | |||||
} | |||||
@GetMapping("/update/{id}") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||||
public User update(@PathVariable Long id) { | |||||
return userService.update(id); | |||||
} | |||||
@GetMapping("/delete/{id}") | |||||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||||
public String delete(@PathVariable Long id) { | |||||
User user = userService.delete(id); | |||||
if (user == null) { | |||||
return "用户不存在"; | |||||
} else { | |||||
return user.getName() + "删除成功"; | |||||
} | |||||
} | |||||
} |
@@ -1,71 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis.dao; | |||||
import com.google.common.collect.Lists; | |||||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
import java.util.concurrent.atomic.AtomicLong; | |||||
@Slf4j | |||||
@Component | |||||
public class UserDao { | |||||
private static List<User> users = Lists.newArrayList(); | |||||
private static AtomicLong SEQ = new AtomicLong(0L); | |||||
public User save() { | |||||
log.info("save....."); | |||||
User user = new User(); | |||||
user.setId(SEQ.get()); | |||||
user.setName("xkcoding" + SEQ.get()); | |||||
user.setBirthDay(new Date()); | |||||
users.add(user); | |||||
SEQ.getAndIncrement(); | |||||
return user; | |||||
} | |||||
public User update(Long id) { | |||||
log.info("update....."); | |||||
for (User user1 : users) { | |||||
if (user1.getId().equals(id)) { | |||||
user1.setName("修改后的名字"); | |||||
return user1; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public User delete(Long id) { | |||||
log.info("delete....."); | |||||
User user = find(id); | |||||
users.remove(user); | |||||
return user; | |||||
} | |||||
public List<User> find() { | |||||
log.info("findAll....."); | |||||
return users; | |||||
} | |||||
public User find(String name) { | |||||
log.info("findByName....."); | |||||
for (User user : users) { | |||||
if (user.getName().equals(name)) { | |||||
return user; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public User find(Long id) { | |||||
log.info("findById....."); | |||||
for (User user : users) { | |||||
if (user.getId().equals(id)) { | |||||
return user; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -1,14 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis.entity; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.util.Date; | |||||
@Data | |||||
public class User implements Serializable { | |||||
private static final long serialVersionUID = 1442134563392432775L; | |||||
private Long id; | |||||
private String name; | |||||
private Date birthDay; | |||||
} |
@@ -1,19 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis.service; | |||||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||||
import java.util.List; | |||||
public interface UserService { | |||||
User save(); | |||||
User update(Long id); | |||||
User delete(Long id); | |||||
List<User> find(); | |||||
User find(Long id); | |||||
User find(String name); | |||||
} |
@@ -1,47 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis.service.impl; | |||||
import com.xkcoding.springbootdemocacheredis.dao.UserDao; | |||||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||||
import com.xkcoding.springbootdemocacheredis.service.UserService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.cache.annotation.CacheConfig; | |||||
import org.springframework.cache.annotation.CachePut; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
@Service | |||||
public class UserServiceImpl implements UserService { | |||||
@Autowired | |||||
private UserDao userDao; | |||||
@Override | |||||
public User save() { | |||||
return userDao.save(); | |||||
} | |||||
@Override | |||||
public User update(Long id) { | |||||
return userDao.update(id); | |||||
} | |||||
@Override | |||||
public User delete(Long id) { | |||||
return userDao.delete(id); | |||||
} | |||||
@Override | |||||
public List<User> find() { | |||||
return userDao.find(); | |||||
} | |||||
@Override | |||||
public User find(Long id) { | |||||
return userDao.find(id); | |||||
} | |||||
@Override | |||||
public User find(String name) { | |||||
return userDao.find(name); | |||||
} | |||||
} |
@@ -1,7 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
redis: | |||||
host: localhost | |||||
port: 6379 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemocacheredis; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoCacheRedisApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
/target/ | |||||
!.mvn/wrapper/maven-wrapper.jar | |||||
### STS ### | |||||
.apt_generated | |||||
.classpath | |||||
.factorypath | |||||
.project | |||||
.settings | |||||
.springBeans | |||||
.sts4-cache | |||||
### IntelliJ IDEA ### | |||||
.idea | |||||
*.iws | |||||
*.iml | |||||
*.ipr | |||||
### NetBeans ### | |||||
/nbproject/private/ | |||||
/build/ | |||||
/nbbuild/ | |||||
/dist/ | |||||
/nbdist/ | |||||
/.nb-gradle/ |
@@ -1,118 +0,0 @@ | |||||
# spring-boot-demo-dubbo-parent | |||||
依赖 [非官方的spring-boot-starter-dubbo](https://gitee.com/reger/spring-boot-starter-dubbo) | |||||
更新 springboot 版本为 2.0.1.RELEASE | |||||
本身是个父依赖,包含了3个 module | |||||
### 各 Module 介绍 | |||||
| 名称 | 作用 | | |||||
| :----------------------------------------------------------- | :-------------------------------------- | | |||||
| [spring-boot-demo-dubbo-api](./spring-boot-demo-dubbo-api/pom.xml) | Spring Boot 与 Dubbo 整合抽取的服务接口 | | |||||
| [spring-boot-demo-dubbo-provider](./spring-boot-demo-dubbo-provider/pom.xml) | Spring Boot 与 Dubbo 整合服务的提供方 | | |||||
| [spring-boot-demo-dubbo-consumer](./spring-boot-demo-dubbo-consumer/pom.xml) | Spring Boot 与 Dubbo 整合服务的消费方 | | |||||
### pom.xml | |||||
```xml | |||||
<?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.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>pom</packaging> | |||||
<name>spring-boot-demo-dubbo-parent</name> | |||||
<description>Spring Boot 与 Dubbo 整合的父依赖</description> | |||||
<parent> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-parent</artifactId> | |||||
<version>2.0.1.RELEASE</version> | |||||
<relativePath/> <!-- lookup parent from repository --> | |||||
</parent> | |||||
<modules> | |||||
<module>spring-boot-demo-dubbo-api</module> | |||||
<module>spring-boot-demo-dubbo-provider</module> | |||||
<module>spring-boot-demo-dubbo-consumer</module> | |||||
</modules> | |||||
<properties> | |||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
<java.version>1.8</java.version> | |||||
<spring-boot-starter-dubbo.version>1.1.1</spring-boot-starter-dubbo.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.gitee.reger</groupId> | |||||
<artifactId>spring-boot-starter-dubbo</artifactId> | |||||
<version>${spring-boot-starter-dubbo.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<version>1.16.20</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-test</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-api</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### 步骤 | |||||
1. 启动本地的 `Zookeeper` 服务,端口号为 **2181** | |||||
> 这里 `Zookeeper` 可以直接使用单机版,如果需要配置集群版的,可以参考 http://xkcoding.com/2017/11/01/zookeeper-cluster.html | |||||
2. 启动两个 `spring-boot-demo-dubbo-provider` 程序,端口号分别使用 **8082**、**8083** | |||||
3. 启动 `spring-boot-demo-dubbo-consumer` 程序,端口号为 **9090** | |||||
4. 浏览器输入 http://localhost:9090/greet?name=test | |||||
可以看到,**8082**和**8083**端口随机打印 | |||||
> Hello, test, from port: 8082 | |||||
或 | |||||
> Hello, test, from port: 8083 | |||||
5. 本地启动 `dubbo-admin` 可以查看服务提供方和消费方,也可以配置负载均衡策略等等 | |||||
> 关于 `dubbo-admin` 的安装和配置等,可以参考 http://xkcoding.com/2017/11/08/dubbo-admin-install.html |
@@ -1,74 +0,0 @@ | |||||
<?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.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>pom</packaging> | |||||
<name>spring-boot-demo-dubbo-parent</name> | |||||
<description>Spring Boot 与 Dubbo 整合的父依赖</description> | |||||
<parent> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-parent</artifactId> | |||||
<version>2.0.1.RELEASE</version> | |||||
<relativePath/> <!-- lookup parent from repository --> | |||||
</parent> | |||||
<modules> | |||||
<module>spring-boot-demo-dubbo-api</module> | |||||
<module>spring-boot-demo-dubbo-provider</module> | |||||
<module>spring-boot-demo-dubbo-consumer</module> | |||||
</modules> | |||||
<properties> | |||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
<java.version>1.8</java.version> | |||||
<spring-boot-starter-dubbo.version>1.1.1</spring-boot-starter-dubbo.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.gitee.reger</groupId> | |||||
<artifactId>spring-boot-starter-dubbo</artifactId> | |||||
<version>${spring-boot-starter-dubbo.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<version>1.16.20</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-test</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-api</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -1,61 +0,0 @@ | |||||
# spring-boot-demo-dubbo-api | |||||
Spring Boot 与 Dubbo 整合抽取的服务接口 | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-api</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-api</name> | |||||
<description>Spring Boot 与 Dubbo 整合抽取的服务接口</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### HelloService.java | |||||
```java | |||||
package com.xkcoding.springbootdemodubboapi.service; | |||||
/** | |||||
* <p> | |||||
* HelloService | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboapi.service | |||||
* @description: HelloService | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:13 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
public interface HelloService { | |||||
String hello(String name); | |||||
} | |||||
``` | |||||
@@ -1,29 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-api</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-api</name> | |||||
<description>Spring Boot 与 Dubbo 整合抽取的服务接口</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -1,18 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboapi.service; | |||||
/** | |||||
* <p> | |||||
* HelloService | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboapi.service | |||||
* @description: HelloService | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:13 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
public interface HelloService { | |||||
String hello(String name); | |||||
} |
@@ -1,165 +0,0 @@ | |||||
# spring-boot-demo-dubbo-consumer | |||||
Spring Boot 与 Dubbo 整合服务的消费方 | |||||
依赖 [spring-boot-demo-dubbo-api](../spring-boot-demo-dubbo-api/pom.xml) | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-consumer</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-consumer</name> | |||||
<description>Spring Boot 与 Dubbo 整合服务的消费方</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<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> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 9090 | |||||
spring: | |||||
dubbo: | |||||
application: | |||||
name: dubbo-consumer | |||||
base-package: com.xkcoding.springbootdemodubboconsumer.service # dubbo服务调用者所在的包 | |||||
registry: | |||||
address: 127.0.0.1 # zookeeper注册中心的地址 | |||||
port: 2181 # zookeeper注册中心的端口 | |||||
consumer: | |||||
timeout: 1000 | |||||
check: true # 服务启动时检查被调用服务是否可用 | |||||
retries: 2 | |||||
``` | |||||
### GreetController.java | |||||
```java | |||||
package com.xkcoding.springbootdemodubboconsumer.controller; | |||||
import com.xkcoding.springbootdemodubboconsumer.service.GreetService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
/** | |||||
* <p> | |||||
* GreetController | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.controller | |||||
* @description: GreetController | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:29 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@RequestMapping("/greet") | |||||
public class GreetController { | |||||
@Autowired | |||||
private GreetService greetService; | |||||
@GetMapping("") | |||||
public String hello(@RequestParam String name) { | |||||
return greetService.greeting(name); | |||||
} | |||||
} | |||||
``` | |||||
### GreetService.java | |||||
```java | |||||
package com.xkcoding.springbootdemodubboconsumer.service; | |||||
/** | |||||
* <p> | |||||
* GreetService | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.service | |||||
* @description: GreetService | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:30 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
public interface GreetService { | |||||
String greeting(String name); | |||||
} | |||||
``` | |||||
### GreetServiceImpl.java | |||||
代码中的 `@Service` 使用的是 `Spring` 的注解,而不是 `Dubbo` 的注解 | |||||
代码中的 `@Inject` 可以替换成 `Dubbo` 提供的 `@Reference`,效果相同 | |||||
```java | |||||
package com.xkcoding.springbootdemodubboconsumer.service.impl; | |||||
import com.reger.dubbo.annotation.Inject; | |||||
import com.xkcoding.springbootdemodubboapi.service.HelloService; | |||||
import com.xkcoding.springbootdemodubboconsumer.service.GreetService; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* GreetServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.service.impl | |||||
* @description: GreetServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:31 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
public class GreetServiceImpl implements GreetService { | |||||
@Inject | |||||
private HelloService helloService; | |||||
@Override | |||||
public String greeting(String name) { | |||||
return helloService.hello(name); | |||||
} | |||||
} | |||||
``` | |||||
@@ -1,35 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-consumer</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-consumer</name> | |||||
<description>Spring Boot 与 Dubbo 整合服务的消费方</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<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> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboconsumer; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoDubboConsumerApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoDubboConsumerApplication.class, args); | |||||
} | |||||
} |
@@ -1,33 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboconsumer.controller; | |||||
import com.xkcoding.springbootdemodubboconsumer.service.GreetService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
/** | |||||
* <p> | |||||
* GreetController | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.controller | |||||
* @description: GreetController | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:29 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@RequestMapping("/greet") | |||||
public class GreetController { | |||||
@Autowired | |||||
private GreetService greetService; | |||||
@GetMapping("") | |||||
public String hello(@RequestParam String name) { | |||||
return greetService.greeting(name); | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboconsumer.service; | |||||
/** | |||||
* <p> | |||||
* GreetService | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.service | |||||
* @description: GreetService | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:30 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
public interface GreetService { | |||||
String greeting(String name); | |||||
} |
@@ -1,30 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboconsumer.service.impl; | |||||
import com.reger.dubbo.annotation.Inject; | |||||
import com.xkcoding.springbootdemodubboapi.service.HelloService; | |||||
import com.xkcoding.springbootdemodubboconsumer.service.GreetService; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* GreetServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboconsumer.service.impl | |||||
* @description: GreetServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:31 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
public class GreetServiceImpl implements GreetService { | |||||
@Inject | |||||
private HelloService helloService; | |||||
@Override | |||||
public String greeting(String name) { | |||||
return helloService.hello(name); | |||||
} | |||||
} |
@@ -1,14 +0,0 @@ | |||||
server: | |||||
port: 9090 | |||||
spring: | |||||
dubbo: | |||||
application: | |||||
name: dubbo-consumer | |||||
base-package: com.xkcoding.springbootdemodubboconsumer.service # dubbo服务调用者所在的包 | |||||
registry: | |||||
address: 127.0.0.1 # zookeeper注册中心的地址 | |||||
port: 2181 # zookeeper注册中心的端口 | |||||
consumer: | |||||
timeout: 1000 | |||||
check: true # 服务启动时检查被调用服务是否可用 | |||||
retries: 2 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboconsumer; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoDubboConsumerApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,106 +0,0 @@ | |||||
# spring-boot-demo-dubbo-provider | |||||
Spring Boot 与 Dubbo 整合服务的提供方 | |||||
依赖 [spring-boot-demo-dubbo-api](../spring-boot-demo-dubbo-api/pom.xml) | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-provider</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-provider</name> | |||||
<description>Spring Boot 与 Dubbo 整合服务的提供方</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<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> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8082 | |||||
spring: | |||||
dubbo: | |||||
application: | |||||
name: dubbo-provider | |||||
base-package: com.xkcoding.springbootdemodubboprovider.service # dubbo服务发布者所在的包 | |||||
registry: | |||||
address: 127.0.0.1 # zookeeper注册中心的地址 | |||||
port: 2181 # zookeeper注册中心的端口 | |||||
protocol: | |||||
name: dubbo | |||||
serialization: hessian2 | |||||
provider: | |||||
retries: 0 | |||||
``` | |||||
### HelloServiceImpl.java | |||||
代码中的 `@Service` 使用的是 `Dubbo` 的注解,而不是 `Spring` 的注解 | |||||
```java | |||||
package com.xkcoding.springbootdemodubboprovider.service.impl; | |||||
import com.alibaba.dubbo.config.annotation.Service; | |||||
import com.xkcoding.springbootdemodubboapi.service.HelloService; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
/** | |||||
* <p> | |||||
* HelloServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboprovider.service.impl | |||||
* @description: HelloServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:24 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
@Slf4j | |||||
public class HelloServiceImpl implements HelloService { | |||||
@Value("${server.port}") | |||||
private Integer port; | |||||
@Override | |||||
public String hello(String name) { | |||||
log.info("Hello, {}, from port: {}",name, port); | |||||
return "Hello, " + name + ", from port: " + port; | |||||
} | |||||
} | |||||
``` | |||||
@@ -1,36 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-dubbo-provider</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-dubbo-provider</name> | |||||
<description>Spring Boot 与 Dubbo 整合服务的提供方</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-dubbo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<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> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboprovider; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoDubboProviderApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoDubboProviderApplication.class, args); | |||||
} | |||||
} |
@@ -1,32 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboprovider.service.impl; | |||||
import com.alibaba.dubbo.config.annotation.Service; | |||||
import com.xkcoding.springbootdemodubboapi.service.HelloService; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
/** | |||||
* <p> | |||||
* HelloServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemodubboprovider.service.impl | |||||
* @description: HelloServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/4/17 下午5:24 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
@Slf4j | |||||
public class HelloServiceImpl implements HelloService { | |||||
@Value("${server.port}") | |||||
private Integer port; | |||||
@Override | |||||
public String hello(String name) { | |||||
log.info("Hello, {}, from port: {}",name, port); | |||||
return "Hello, " + name + ", from port: " + port; | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
server: | |||||
port: 8082 | |||||
spring: | |||||
dubbo: | |||||
application: | |||||
name: dubbo-provider | |||||
base-package: com.xkcoding.springbootdemodubboprovider.service # dubbo服务发布者所在的包 | |||||
registry: | |||||
address: 127.0.0.1 # zookeeper注册中心的地址 | |||||
port: 2181 # zookeeper注册中心的端口 | |||||
protocol: | |||||
name: dubbo | |||||
serialization: hessian2 | |||||
provider: | |||||
retries: 0 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemodubboprovider; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoDubboProviderApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,24 +0,0 @@ | |||||
target/ | |||||
!.mvn/wrapper/maven-wrapper.jar | |||||
### STS ### | |||||
.apt_generated | |||||
.classpath | |||||
.factorypath | |||||
.project | |||||
.settings | |||||
.springBeans | |||||
### IntelliJ IDEA ### | |||||
.idea | |||||
*.iws | |||||
*.iml | |||||
*.ipr | |||||
### NetBeans ### | |||||
nbproject/private/ | |||||
build/ | |||||
nbbuild/ | |||||
dist/ | |||||
nbdist/ | |||||
.nb-gradle/ |
@@ -1,284 +0,0 @@ | |||||
# spring-boot-demo-elasticsearch | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent) | |||||
> 关于 ES 的更多内容,可以参考[官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html) | |||||
> | |||||
> 本例对应博客文章地址,http://xkcoding.com/2018/01/12/elasticsearch_note.html | |||||
ElasticSearch 的 demo 我这里没有使用 spring-data-elasticsearch,我使用的是原生的方式 | |||||
操作 ElasticSearch 由很多种方式: | |||||
1. ES 官方提供的原生方式,**本例子使用这种方式**,这种方式的好处是高度自定义,并且可以使用最新的 ES 版本,缺点就是所有操作都得自己写。 | |||||
2. 使用 Spring 官方提供的 spring-data-elasticsearch,这里给出地址 https://projects.spring.io/spring-data-elasticsearch/ ,采用的方式类似 JPA,并且为 SpringBoot 提供了一个 `spring-boot-starter-data-elasticsearch`,优点是操作 ES 的方式采用了 JPA 的方式,都已经封装好了,缺点是版本得随着官方慢慢迭代,不能使用 ES 的最新特性。 | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-elasticsearch</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-elasticsearch</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<!--默认 Spring-Boot 依赖的 ES 版本是 2.X 版本,这里采用最新版--> | |||||
<elasticsearch.version>6.1.1</elasticsearch.version> | |||||
</properties> | |||||
<dependencies> | |||||
<!-- ES --> | |||||
<dependency> | |||||
<groupId>org.elasticsearch.client</groupId> | |||||
<artifactId>transport</artifactId> | |||||
<version>${elasticsearch.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.apache.logging.log4j</groupId> | |||||
<artifactId>log4j-core</artifactId> | |||||
<version>2.7</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-elasticsearch</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
elasticsearch: | |||||
host: 127.0.0.1 | |||||
port: 9300 | |||||
cluster: | |||||
name: xkcoding | |||||
``` | |||||
ElasticSearchConfig.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* ES 的配置类 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.config | |||||
* @description: ES 的配置类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午4:41 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Configuration | |||||
public class ElasticSearchConfig { | |||||
@Value("${elasticsearch.host}") | |||||
private String host; | |||||
@Value("${elasticsearch.port}") | |||||
private int port; | |||||
@Value("${elasticsearch.cluster.name}") | |||||
private String clusterName; | |||||
@Bean | |||||
public TransportClient esClient() throws UnknownHostException { | |||||
Settings settings = Settings.builder().put("cluster.name", this.clusterName).put("client.transport.sniff", true).build(); | |||||
TransportAddress master = new TransportAddress(InetAddress.getByName(host), port); | |||||
TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(master); | |||||
return client; | |||||
} | |||||
} | |||||
``` | |||||
PersonController.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* Person Controller | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.web.controller | |||||
* @description: Person Controller | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午5:06 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@Slf4j | |||||
public class PersonController { | |||||
public static final String INDEX = "people"; | |||||
public static final String TYPE = "person"; | |||||
@Autowired | |||||
private TransportClient esClient; | |||||
/** | |||||
* 插入一条数据到 ES 中,id 由 ES 生成 | |||||
* | |||||
* @param name 名称 | |||||
* @param country 国籍 | |||||
* @param age 年龄 | |||||
* @param birthday 生日 | |||||
* @return 插入数据的主键 | |||||
*/ | |||||
@PostMapping("/person") | |||||
public ApiResponse add(@RequestParam String name, @RequestParam String country, @RequestParam Integer age, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birthday) { | |||||
try { | |||||
XContentBuilder content = XContentFactory.jsonBuilder().startObject().field("name", name).field("country", country).field("age", age).field("birthday", birthday.getTime()).endObject(); | |||||
IndexResponse response = esClient.prepareIndex(INDEX, TYPE).setSource(content).get(); | |||||
return ApiResponse.ofSuccess(response.getId()); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
} | |||||
/** | |||||
* 根据 id 删除 ES 的一条记录 | |||||
* | |||||
* @param id ES 中的 id | |||||
* @return DELETED 代表删除 | |||||
*/ | |||||
@DeleteMapping("/person/{id}") | |||||
public ApiResponse delete(@PathVariable String id) { | |||||
DeleteResponse response = esClient.prepareDelete(INDEX, TYPE, id).get(); | |||||
return ApiResponse.ofSuccess(response.getResult()); | |||||
} | |||||
/** | |||||
* 根据主键,修改传递字段对应的值 | |||||
* | |||||
* @param id ES 中的 id | |||||
* @param name 姓名 | |||||
* @param country 国籍 | |||||
* @param age 年龄 | |||||
* @param birthday 生日 | |||||
* @return UPDATED 代表文档修改成功 | |||||
*/ | |||||
@PutMapping("/person/{id}") | |||||
public ApiResponse update(@PathVariable String id, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "country", required = false) String country, @RequestParam(value = "age", required = false) Integer age, @RequestParam(value = "birthday", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birthday) { | |||||
UpdateRequest request = new UpdateRequest(INDEX, TYPE, id); | |||||
try { | |||||
XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); | |||||
if (!Strings.isNullOrEmpty(name)) { | |||||
builder.field("name", name); | |||||
} | |||||
if (!Strings.isNullOrEmpty(country)) { | |||||
builder.field("country", country); | |||||
} | |||||
if (age != null && age > 0) { | |||||
builder.field("age", age); | |||||
} | |||||
if (birthday != null) { | |||||
builder.field("birthday", birthday.getTime()); | |||||
} | |||||
builder.endObject(); | |||||
request.doc(builder); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
try { | |||||
UpdateResponse response = esClient.update(request).get(); | |||||
return ApiResponse.ofSuccess(response); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
} | |||||
/** | |||||
* 简单查询 根据 id 查 ES 中的文档内容 | |||||
* | |||||
* @param id ES 中存储的 id | |||||
* @return 对应 id 的文档内容 | |||||
*/ | |||||
@GetMapping("/person/{id}") | |||||
public ApiResponse get(@PathVariable String id) { | |||||
GetResponse response = esClient.prepareGet(INDEX, TYPE, id).get(); | |||||
if (!response.isExists() || response.isSourceEmpty()) { | |||||
return ApiResponse.ofStatus(Status.NOT_FOUND); | |||||
} | |||||
return ApiResponse.ofSuccess(response.getSource()); | |||||
} | |||||
/** | |||||
* 复合查询,根据传进来的条件,查询具体内容 | |||||
* | |||||
* @param name 根据姓名匹配 | |||||
* @param country 根据国籍匹配 | |||||
* @param gtAge 大于年龄 | |||||
* @param ltAge 小于年龄 | |||||
* @return 满足条件的文档内容 | |||||
*/ | |||||
@PostMapping("/person/query") | |||||
public ApiResponse query(@RequestParam(value = "name", required = false) String name, | |||||
@RequestParam(value = "country", required = false) String country, | |||||
@RequestParam(value = "gt_age", defaultValue = "0") int gtAge, | |||||
@RequestParam(value = "lt_age", required = false) Integer ltAge) { | |||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); | |||||
if (!Strings.isNullOrEmpty(name)) { | |||||
boolQueryBuilder.must(QueryBuilders.matchQuery("name", name)); | |||||
} | |||||
if (!Strings.isNullOrEmpty(country)) { | |||||
boolQueryBuilder.must(QueryBuilders.matchQuery("country", country)); | |||||
} | |||||
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").from(gtAge); | |||||
if (ltAge != null && ltAge > 0) { | |||||
rangeQueryBuilder.to(ltAge); | |||||
} | |||||
boolQueryBuilder.filter(rangeQueryBuilder); | |||||
SearchRequestBuilder searchRequestBuilder = esClient.prepareSearch(INDEX) | |||||
.setTypes(TYPE) | |||||
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH) | |||||
.setQuery(boolQueryBuilder) | |||||
.setFrom(0) | |||||
.setSize(20); | |||||
log.info("【query】:{}", searchRequestBuilder); | |||||
SearchResponse searchResponse = searchRequestBuilder.get(); | |||||
List<Map<String, Object>> result = Lists.newArrayList(); | |||||
searchResponse.getHits().forEach(hit -> { | |||||
result.add(hit.getSourceAsMap()); | |||||
}); | |||||
return ApiResponse.ofSuccess(result); | |||||
} | |||||
} | |||||
``` | |||||
@@ -1,44 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-elasticsearch</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-elasticsearch</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<!--默认 Spring-Boot 依赖的 ES 版本是 2.X 版本,这里采用最新版--> | |||||
<elasticsearch.version>6.1.1</elasticsearch.version> | |||||
</properties> | |||||
<dependencies> | |||||
<!-- ES --> | |||||
<dependency> | |||||
<groupId>org.elasticsearch.client</groupId> | |||||
<artifactId>transport</artifactId> | |||||
<version>${elasticsearch.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.apache.logging.log4j</groupId> | |||||
<artifactId>log4j-core</artifactId> | |||||
<version>2.7</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-elasticsearch</finalName> | |||||
</build> | |||||
</project> |
@@ -1,26 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
/** | |||||
* <p> | |||||
* 应用启动类 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.web.controller | |||||
* @description: 应用启动类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午5:06 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@SpringBootApplication | |||||
public class SpringBootDemoElasticsearchApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoElasticsearchApplication.class, args); | |||||
} | |||||
} |
@@ -1,46 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch.config; | |||||
import org.elasticsearch.client.transport.TransportClient; | |||||
import org.elasticsearch.common.settings.Settings; | |||||
import org.elasticsearch.common.transport.TransportAddress; | |||||
import org.elasticsearch.transport.client.PreBuiltTransportClient; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import java.net.InetAddress; | |||||
import java.net.UnknownHostException; | |||||
/** | |||||
* <p> | |||||
* ES 的配置类 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.config | |||||
* @description: ES 的配置类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午4:41 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Configuration | |||||
public class ElasticSearchConfig { | |||||
@Value("${elasticsearch.host}") | |||||
private String host; | |||||
@Value("${elasticsearch.port}") | |||||
private int port; | |||||
@Value("${elasticsearch.cluster.name}") | |||||
private String clusterName; | |||||
@Bean | |||||
public TransportClient esClient() throws UnknownHostException { | |||||
Settings settings = Settings.builder().put("cluster.name", this.clusterName).put("client.transport.sniff", true).build(); | |||||
TransportAddress master = new TransportAddress(InetAddress.getByName(host), port); | |||||
TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(master); | |||||
return client; | |||||
} | |||||
} |
@@ -1,48 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch.web.base; | |||||
import lombok.Data; | |||||
/** | |||||
* <p> | |||||
* 统一接口返回类型 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch | |||||
* @description: 统一接口返回类型 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午5:34 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Data | |||||
public class ApiResponse { | |||||
private int code; | |||||
private String message; | |||||
private Object data; | |||||
private boolean more; | |||||
public ApiResponse(int code, String message, Object data) { | |||||
this.code = code; | |||||
this.message = message; | |||||
this.data = data; | |||||
} | |||||
public ApiResponse() { | |||||
this.code = Status.SUCCESS.getCode(); | |||||
this.message = Status.SUCCESS.getMsg(); | |||||
} | |||||
public static ApiResponse ofMessage(int code, String message) { | |||||
return new ApiResponse(code, message, null); | |||||
} | |||||
public static ApiResponse ofSuccess(Object data) { | |||||
return new ApiResponse(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg(), data); | |||||
} | |||||
public static ApiResponse ofStatus(Status status) { | |||||
return new ApiResponse(status.getCode(), status.getMsg(), null); | |||||
} | |||||
} |
@@ -1,29 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch.web.base; | |||||
import lombok.Getter; | |||||
/** | |||||
* <p> | |||||
* 通用状态码 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.web.base | |||||
* @description: 通用状态码 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午5:35 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Getter | |||||
public enum Status { | |||||
SUCCESS(200, "OK"), BAD_REQUEST(400, "Bad Request"), NOT_FOUND(404, "Not Found"), INTERNAL_SERVER_ERROR(500, "Unknown Internal Error"); | |||||
private int code; | |||||
private String msg; | |||||
Status(int code, String msg) { | |||||
this.code = code; | |||||
this.msg = msg; | |||||
} | |||||
} |
@@ -1,194 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch.web.controller; | |||||
import com.google.common.base.Strings; | |||||
import com.google.common.collect.Lists; | |||||
import com.xkcoding.springbootdemoelasticsearch.web.base.ApiResponse; | |||||
import com.xkcoding.springbootdemoelasticsearch.web.base.Status; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.elasticsearch.action.delete.DeleteResponse; | |||||
import org.elasticsearch.action.get.GetResponse; | |||||
import org.elasticsearch.action.index.IndexResponse; | |||||
import org.elasticsearch.action.search.SearchRequestBuilder; | |||||
import org.elasticsearch.action.search.SearchResponse; | |||||
import org.elasticsearch.action.search.SearchType; | |||||
import org.elasticsearch.action.update.UpdateRequest; | |||||
import org.elasticsearch.action.update.UpdateResponse; | |||||
import org.elasticsearch.client.transport.TransportClient; | |||||
import org.elasticsearch.common.xcontent.XContentBuilder; | |||||
import org.elasticsearch.common.xcontent.XContentFactory; | |||||
import org.elasticsearch.index.query.BoolQueryBuilder; | |||||
import org.elasticsearch.index.query.QueryBuilders; | |||||
import org.elasticsearch.index.query.RangeQueryBuilder; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.format.annotation.DateTimeFormat; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import java.io.IOException; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* <p> | |||||
* Person Controller | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoelasticsearch.web.controller | |||||
* @description: Person Controller | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/1/18 下午5:06 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@Slf4j | |||||
public class PersonController { | |||||
public static final String INDEX = "people"; | |||||
public static final String TYPE = "person"; | |||||
@Autowired | |||||
private TransportClient esClient; | |||||
/** | |||||
* 插入一条数据到 ES 中,id 由 ES 生成 | |||||
* | |||||
* @param name 名称 | |||||
* @param country 国籍 | |||||
* @param age 年龄 | |||||
* @param birthday 生日 | |||||
* @return 插入数据的主键 | |||||
*/ | |||||
@PostMapping("/person") | |||||
public ApiResponse add(@RequestParam String name, @RequestParam String country, @RequestParam Integer age, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birthday) { | |||||
try { | |||||
XContentBuilder content = XContentFactory.jsonBuilder().startObject().field("name", name).field("country", country).field("age", age).field("birthday", birthday.getTime()).endObject(); | |||||
IndexResponse response = esClient.prepareIndex(INDEX, TYPE).setSource(content).get(); | |||||
return ApiResponse.ofSuccess(response.getId()); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
} | |||||
/** | |||||
* 根据 id 删除 ES 的一条记录 | |||||
* | |||||
* @param id ES 中的 id | |||||
* @return DELETED 代表删除 | |||||
*/ | |||||
@DeleteMapping("/person/{id}") | |||||
public ApiResponse delete(@PathVariable String id) { | |||||
DeleteResponse response = esClient.prepareDelete(INDEX, TYPE, id).get(); | |||||
return ApiResponse.ofSuccess(response.getResult()); | |||||
} | |||||
/** | |||||
* 根据主键,修改传递字段对应的值 | |||||
* | |||||
* @param id ES 中的 id | |||||
* @param name 姓名 | |||||
* @param country 国籍 | |||||
* @param age 年龄 | |||||
* @param birthday 生日 | |||||
* @return UPDATED 代表文档修改成功 | |||||
*/ | |||||
@PutMapping("/person/{id}") | |||||
public ApiResponse update(@PathVariable String id, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "country", required = false) String country, @RequestParam(value = "age", required = false) Integer age, @RequestParam(value = "birthday", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birthday) { | |||||
UpdateRequest request = new UpdateRequest(INDEX, TYPE, id); | |||||
try { | |||||
XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); | |||||
if (!Strings.isNullOrEmpty(name)) { | |||||
builder.field("name", name); | |||||
} | |||||
if (!Strings.isNullOrEmpty(country)) { | |||||
builder.field("country", country); | |||||
} | |||||
if (age != null && age > 0) { | |||||
builder.field("age", age); | |||||
} | |||||
if (birthday != null) { | |||||
builder.field("birthday", birthday.getTime()); | |||||
} | |||||
builder.endObject(); | |||||
request.doc(builder); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
try { | |||||
UpdateResponse response = esClient.update(request).get(); | |||||
return ApiResponse.ofSuccess(response); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); | |||||
} | |||||
} | |||||
/** | |||||
* 简单查询 根据 id 查 ES 中的文档内容 | |||||
* | |||||
* @param id ES 中存储的 id | |||||
* @return 对应 id 的文档内容 | |||||
*/ | |||||
@GetMapping("/person/{id}") | |||||
public ApiResponse get(@PathVariable String id) { | |||||
GetResponse response = esClient.prepareGet(INDEX, TYPE, id).get(); | |||||
if (!response.isExists() || response.isSourceEmpty()) { | |||||
return ApiResponse.ofStatus(Status.NOT_FOUND); | |||||
} | |||||
return ApiResponse.ofSuccess(response.getSource()); | |||||
} | |||||
/** | |||||
* 复合查询,根据传进来的条件,查询具体内容 | |||||
* | |||||
* @param name 根据姓名匹配 | |||||
* @param country 根据国籍匹配 | |||||
* @param gtAge 大于年龄 | |||||
* @param ltAge 小于年龄 | |||||
* @return 满足条件的文档内容 | |||||
*/ | |||||
@PostMapping("/person/query") | |||||
public ApiResponse query(@RequestParam(value = "name", required = false) String name, | |||||
@RequestParam(value = "country", required = false) String country, | |||||
@RequestParam(value = "gt_age", defaultValue = "0") int gtAge, | |||||
@RequestParam(value = "lt_age", required = false) Integer ltAge) { | |||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); | |||||
if (!Strings.isNullOrEmpty(name)) { | |||||
boolQueryBuilder.must(QueryBuilders.matchQuery("name", name)); | |||||
} | |||||
if (!Strings.isNullOrEmpty(country)) { | |||||
boolQueryBuilder.must(QueryBuilders.matchQuery("country", country)); | |||||
} | |||||
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").from(gtAge); | |||||
if (ltAge != null && ltAge > 0) { | |||||
rangeQueryBuilder.to(ltAge); | |||||
} | |||||
boolQueryBuilder.filter(rangeQueryBuilder); | |||||
SearchRequestBuilder searchRequestBuilder = esClient.prepareSearch(INDEX) | |||||
.setTypes(TYPE) | |||||
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH) | |||||
.setQuery(boolQueryBuilder) | |||||
.setFrom(0) | |||||
.setSize(20); | |||||
log.info("【query】:{}", searchRequestBuilder); | |||||
SearchResponse searchResponse = searchRequestBuilder.get(); | |||||
List<Map<String, Object>> result = Lists.newArrayList(); | |||||
searchResponse.getHits().forEach(hit -> { | |||||
result.add(hit.getSourceAsMap()); | |||||
}); | |||||
return ApiResponse.ofSuccess(result); | |||||
} | |||||
} |
@@ -1,8 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
elasticsearch: | |||||
host: 127.0.0.1 | |||||
port: 9300 | |||||
cluster: | |||||
name: xkcoding |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoelasticsearch; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoElasticsearchApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,180 +0,0 @@ | |||||
# spring-boot-demo-exceptionhandler | |||||
依赖[spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-thymeleaf`(关于 thymeleaf 的会在后面的模板引擎专门有demo) | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-exceptionhandler</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-exceptionhandler</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-exceptionhandler</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
thymeleaf: | |||||
mode: HTML5 | |||||
encoding: UTF-8 | |||||
content-type: text/html | |||||
cache: false | |||||
``` | |||||
### DemoExceptionHandler.java | |||||
```java | |||||
/** | |||||
* 自定义异常统一处理 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.handler | |||||
* @description: 自定义异常统一处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:37 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@ControllerAdvice | |||||
@Slf4j | |||||
public class DemoExceptionHandler { | |||||
public static final String DEFAULT_ERROR_VIEW = "error"; | |||||
/** | |||||
* 统一 json 异常处理 | |||||
* | |||||
* @param exception DemoJsonException | |||||
* @return 统一返回 json 格式 | |||||
*/ | |||||
@ExceptionHandler(value = DemoJsonException.class) | |||||
@ResponseBody | |||||
public R jsonErrorHandler(DemoJsonException exception) { | |||||
log.error("【DemoJsonException】:{}", exception.getMessage()); | |||||
return R.error(exception); | |||||
} | |||||
/** | |||||
* 统一 页面 异常处理 | |||||
* | |||||
* @param exception DemoPageException | |||||
* @return 统一跳转到异常页面 | |||||
*/ | |||||
@ExceptionHandler(value = DemoPageException.class) | |||||
public ModelAndView pageErrorHandler(DemoPageException exception) { | |||||
log.error("【DemoPageException】:{}", exception.getMessage()); | |||||
ModelAndView view = new ModelAndView(); | |||||
view.addObject("message", exception.getMessage()); | |||||
view.setViewName(DEFAULT_ERROR_VIEW); | |||||
return view; | |||||
} | |||||
} | |||||
``` | |||||
### R.java | |||||
```java | |||||
/** | |||||
* 统一返回的 json 对象 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler | |||||
* @description: 统一返回的 json 对象 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:42 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
@NoArgsConstructor | |||||
@AllArgsConstructor | |||||
public class R<T> { | |||||
private Integer code; | |||||
private String message; | |||||
private T data; | |||||
public R(Status status) { | |||||
this.code = status.getCode(); | |||||
this.message = status.getMessage(); | |||||
} | |||||
public static R success(Integer code, String message, Object data) { | |||||
return new R(code, message, data); | |||||
} | |||||
public static R success() { | |||||
return new R(Status.OK); | |||||
} | |||||
public static R success(String message) { | |||||
return success(message, null); | |||||
} | |||||
public static R success(String message, Object data) { | |||||
return success(Code.SUCCESS.getCode(), message, data); | |||||
} | |||||
public static R error(Integer code, String message, Object data) { | |||||
return new R(code, message, data); | |||||
} | |||||
public static R error(Integer code, String message) { | |||||
return error(code, message, null); | |||||
} | |||||
public static R error(DemoJsonException exception) { | |||||
return error(exception.getCode(), exception.getMessage()); | |||||
} | |||||
} | |||||
``` | |||||
### error.html (在目录 `resources/templates` 下) | |||||
```html | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="http://www.thymeleaf.org"> | |||||
<head lang="en"> | |||||
<meta charset="UTF-8"/> | |||||
<title>统一页面异常处理</title> | |||||
</head> | |||||
<body> | |||||
<h1>统一页面异常处理</h1> | |||||
<div th:text="${message}"></div> | |||||
</body> | |||||
</html> | |||||
``` | |||||
### 其余代码 | |||||
详情请参见本demo。 |
@@ -1,31 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-exceptionhandler</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-exceptionhandler</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-exceptionhandler</finalName> | |||||
</build> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoExceptionhandlerApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoExceptionhandlerApplication.class, args); | |||||
} | |||||
} |
@@ -1,28 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.controller; | |||||
import com.xkcoding.springbootdemoexceptionhandler.domain.R; | |||||
import com.xkcoding.springbootdemoexceptionhandler.exception.DemoJsonException; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
/** | |||||
* 测试 json 异常处理 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.controller | |||||
* @description: 测试 json 异常处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午2:08 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@RequestMapping("/json") | |||||
public class JsonController { | |||||
@GetMapping({"", "/"}) | |||||
public R index() { | |||||
throw new DemoJsonException(501, "DemoJsonException"); | |||||
} | |||||
} |
@@ -1,28 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.controller; | |||||
import com.xkcoding.springbootdemoexceptionhandler.exception.DemoPageException; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.servlet.ModelAndView; | |||||
/** | |||||
* 测试 page 异常处理 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.controller | |||||
* @description: 测试 page 异常处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午2:29 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/page") | |||||
public class PageController { | |||||
@GetMapping({"", "/"}) | |||||
public ModelAndView index() { | |||||
throw new DemoPageException(600, "DemoPageException"); | |||||
} | |||||
} |
@@ -1,63 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.domain; | |||||
import com.xkcoding.springbootdemoexceptionhandler.enums.Code; | |||||
import com.xkcoding.springbootdemoexceptionhandler.enums.Status; | |||||
import com.xkcoding.springbootdemoexceptionhandler.exception.DemoJsonException; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
/** | |||||
* 统一返回的 json 对象 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler | |||||
* @description: 统一返回的 json 对象 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:42 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
@NoArgsConstructor | |||||
@AllArgsConstructor | |||||
public class R<T> { | |||||
private Integer code; | |||||
private String message; | |||||
private T data; | |||||
public R(Status status) { | |||||
this.code = status.getCode(); | |||||
this.message = status.getMessage(); | |||||
} | |||||
public static R success(Integer code, String message, Object data) { | |||||
return new R(code, message, data); | |||||
} | |||||
public static R success() { | |||||
return new R(Status.OK); | |||||
} | |||||
public static R success(String message) { | |||||
return success(message, null); | |||||
} | |||||
public static R success(String message, Object data) { | |||||
return success(Code.SUCCESS.getCode(), message, data); | |||||
} | |||||
public static R error(Integer code, String message, Object data) { | |||||
return new R(code, message, data); | |||||
} | |||||
public static R error(Integer code, String message) { | |||||
return error(code, message, null); | |||||
} | |||||
public static R error(DemoJsonException exception) { | |||||
return error(exception.getCode(), exception.getMessage()); | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.enums; | |||||
import lombok.Getter; | |||||
/** | |||||
* 状态码 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.enums | |||||
* @description: 状态码 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:56 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Getter | |||||
public enum Code { | |||||
SUCCESS(200); | |||||
private Integer code; | |||||
Code(Integer code) { | |||||
this.code = code; | |||||
} | |||||
} |
@@ -1,26 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.enums; | |||||
import lombok.Getter; | |||||
/** | |||||
* 返回状态 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.enums | |||||
* @description: 返回状态 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:47 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Getter | |||||
public enum Status { | |||||
OK(200, "成功"), UNKNOW_ERROR(-1, "未知错误"); | |||||
private Integer code; | |||||
private String message; | |||||
Status(Integer code, String message) { | |||||
this.code = code; | |||||
this.message = message; | |||||
} | |||||
} |
@@ -1,27 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.exception; | |||||
import lombok.Getter; | |||||
/** | |||||
* 统一的 json 异常处理 | |||||
* <p> | |||||
* 要继承 RuntimeException | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.exception | |||||
* @description: 统一的 json 异常处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:32 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Getter | |||||
public class DemoJsonException extends RuntimeException { | |||||
public Integer code; | |||||
public DemoJsonException(Integer code, String message) { | |||||
super(message); | |||||
this.code = code; | |||||
} | |||||
} |
@@ -1,27 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.exception; | |||||
import lombok.Getter; | |||||
/** | |||||
* 统一的页面异常处理 | |||||
* <p> | |||||
* 要继承 RuntimeException | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.exception | |||||
* @description: 统一的页面异常处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:32 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Getter | |||||
public class DemoPageException extends RuntimeException { | |||||
public Integer code; | |||||
public DemoPageException(Integer code, String message) { | |||||
super(message); | |||||
this.code = code; | |||||
} | |||||
} |
@@ -1,55 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler.handler; | |||||
import com.xkcoding.springbootdemoexceptionhandler.domain.R; | |||||
import com.xkcoding.springbootdemoexceptionhandler.exception.DemoJsonException; | |||||
import com.xkcoding.springbootdemoexceptionhandler.exception.DemoPageException; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.web.bind.annotation.ControllerAdvice; | |||||
import org.springframework.web.bind.annotation.ExceptionHandler; | |||||
import org.springframework.web.bind.annotation.ResponseBody; | |||||
import org.springframework.web.servlet.ModelAndView; | |||||
/** | |||||
* 自定义异常统一处理 | |||||
* | |||||
* @package: com.xkcoding.springbootdemoexceptionhandler.handler | |||||
* @description: 自定义异常统一处理 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2017/11/24 下午1:37 | |||||
* @copyright: Copyright (c) 2017 | |||||
* @version: 0.0.1 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@ControllerAdvice | |||||
@Slf4j | |||||
public class DemoExceptionHandler { | |||||
public static final String DEFAULT_ERROR_VIEW = "error"; | |||||
/** | |||||
* 统一 json 异常处理 | |||||
* | |||||
* @param exception DemoJsonException | |||||
* @return 统一返回 json 格式 | |||||
*/ | |||||
@ExceptionHandler(value = DemoJsonException.class) | |||||
@ResponseBody | |||||
public R jsonErrorHandler(DemoJsonException exception) { | |||||
log.error("【DemoJsonException】:{}", exception.getMessage()); | |||||
return R.error(exception); | |||||
} | |||||
/** | |||||
* 统一 页面 异常处理 | |||||
* | |||||
* @param exception DemoPageException | |||||
* @return 统一跳转到异常页面 | |||||
*/ | |||||
@ExceptionHandler(value = DemoPageException.class) | |||||
public ModelAndView pageErrorHandler(DemoPageException exception) { | |||||
log.error("【DemoPageException】:{}", exception.getMessage()); | |||||
ModelAndView view = new ModelAndView(); | |||||
view.addObject("message", exception.getMessage()); | |||||
view.setViewName(DEFAULT_ERROR_VIEW); | |||||
return view; | |||||
} | |||||
} |
@@ -1,9 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
thymeleaf: | |||||
mode: HTML5 | |||||
encoding: UTF-8 | |||||
content-type: text/html | |||||
cache: false |
@@ -1,11 +0,0 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="http://www.thymeleaf.org"> | |||||
<head lang="en"> | |||||
<meta charset="UTF-8"/> | |||||
<title>统一页面异常处理</title> | |||||
</head> | |||||
<body> | |||||
<h1>统一页面异常处理</h1> | |||||
<div th:text="${message}"></div> | |||||
</body> | |||||
</html> |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoexceptionhandler; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoExceptionhandlerApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,84 +0,0 @@ | |||||
# spring-boot-demo-helloworld | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent) | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-helloworld</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-helloworld</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<finalName>spring-boot-demo-helloworld</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### SpringBootDemoHelloworldApplication.java | |||||
```java | |||||
@RestController | |||||
@SpringBootApplication | |||||
@Configuration | |||||
public class SpringBootDemoHelloworldApplication { | |||||
@Value("${spring.boot.demo.helloworld.data.version}") | |||||
private String version; | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoHelloworldApplication.class, args); | |||||
} | |||||
@GetMapping("/hello") | |||||
public Map sayHello(@Value("${author}") String author, @Value("${exclusions}") String exclusions, @Value("${connectionProperties}") String connectionProperties) { | |||||
Map<String, Object> result = Maps.newHashMap(); | |||||
result.put("ret", true); | |||||
result.put("msg", StrUtil.format("hello,world,{}", author)); | |||||
Map<String, Object> data = Maps.newHashMap(); | |||||
data.put("version", version); | |||||
data.put("exclusions", exclusions.split(",")); | |||||
Map<String, Object> connectionProperty = Maps.newHashMap(); | |||||
for (String connection : connectionProperties.split(";")) { | |||||
String[] conn = connection.split("="); | |||||
connectionProperty.put(conn[0], conn[1]); | |||||
} | |||||
data.put("connectionProperties", connectionProperty); | |||||
result.put("data", data); | |||||
return result; | |||||
} | |||||
} | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
boot: | |||||
demo: | |||||
helloworld: | |||||
data: | |||||
version: 1.0.0 | |||||
author: xkcoding | |||||
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" | |||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 | |||||
``` | |||||
@@ -1,24 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-helloworld</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-helloworld</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<finalName>spring-boot-demo-helloworld</finalName> | |||||
</build> | |||||
</project> |
@@ -1,43 +0,0 @@ | |||||
package com.xkcoding.springbootdemohelloworld; | |||||
import com.google.common.collect.*; | |||||
import com.xiaoleilu.hutool.util.StrUtil; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
@RestController | |||||
@SpringBootApplication | |||||
@Configuration | |||||
public class SpringBootDemoHelloworldApplication { | |||||
@Value("${spring.boot.demo.helloworld.data.version}") | |||||
private String version; | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoHelloworldApplication.class, args); | |||||
} | |||||
@GetMapping("/hello") | |||||
public Map sayHello(@Value("${author}") String author, @Value("${exclusions}") String exclusions, @Value("${connectionProperties}") String connectionProperties) { | |||||
Map<String, Object> result = Maps.newHashMap(); | |||||
result.put("ret", true); | |||||
result.put("msg", StrUtil.format("hello,world,{}", author)); | |||||
Map<String, Object> data = Maps.newHashMap(); | |||||
data.put("version", version); | |||||
data.put("exclusions", exclusions.split(",")); | |||||
Map<String, Object> connectionProperty = Maps.newHashMap(); | |||||
for (String connection : connectionProperties.split(";")) { | |||||
String[] conn = connection.split("="); | |||||
connectionProperty.put(conn[0], conn[1]); | |||||
} | |||||
data.put("connectionProperties", connectionProperty); | |||||
result.put("data", data); | |||||
return result; | |||||
} | |||||
} |
@@ -1,12 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
boot: | |||||
demo: | |||||
helloworld: | |||||
data: | |||||
version: 1.0.0 | |||||
author: xkcoding | |||||
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" | |||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemohelloworld; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoHelloworldApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,122 +0,0 @@ | |||||
# spring-boot-demo-logback | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent) | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-logback</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-logback</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<finalName>spring-boot-demo-logback</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### SpringBootDemoLogbackApplication.java | |||||
```java | |||||
@SpringBootApplication | |||||
@Slf4j | |||||
public class SpringBootDemoLogbackApplication { | |||||
public static void main(String[] args) { | |||||
ConfigurableApplicationContext context = SpringApplication.run(SpringBootDemoLogbackApplication.class, args); | |||||
int length = context.getBeanDefinitionNames().length; | |||||
log.trace("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.debug("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.info("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.warn("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.error("Spring boot启动初始化了 {} 个 Bean", length); | |||||
try { | |||||
int i = 0; | |||||
int j = 1 / i; | |||||
} catch (Exception e) { | |||||
log.error("【SpringBootDemoLogbackApplication】启动异常:", e); | |||||
} | |||||
} | |||||
} | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
application: | |||||
name: logback-demo | |||||
``` | |||||
### logback-spring.xml | |||||
```xml | |||||
<?xml version="1.0" encoding="utf-8" ?> | |||||
<configuration> | |||||
<conversionRule conversionWord="clr" | |||||
converterClass="org.springframework.boot.logging.logback.ColorConverter"/> | |||||
<conversionRule conversionWord="wex" | |||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> | |||||
<conversionRule conversionWord="wEx" | |||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> | |||||
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> | |||||
<layout class="ch.qos.logback.classic.PatternLayout"> | |||||
<pattern>【xkcoding】%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} | |||||
</pattern> | |||||
</layout> | |||||
</appender> | |||||
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<!--滚动策略--> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<!--输出路径--> | |||||
<fileNamePattern>${user.dir}/logs/log/logback-demo.%d.log</fileNamePattern> | |||||
</rollingPolicy> | |||||
<encoder> | |||||
<pattern>【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern> | |||||
</encoder> | |||||
</appender> | |||||
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||||
<level>ERROR</level> | |||||
<onMatch>ACCEPT</onMatch> | |||||
<onMismatch>DENY</onMismatch> | |||||
</filter> | |||||
<!--滚动策略--> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<!--输出路径--> | |||||
<fileNamePattern>${user.dir}/logs/error/logback-demo.%d.error</fileNamePattern> | |||||
</rollingPolicy> | |||||
<encoder> | |||||
<pattern>【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern> | |||||
</encoder> | |||||
</appender> | |||||
<root level="info"> | |||||
<appender-ref ref="consoleLog"/> | |||||
<appender-ref ref="fileLog"/> | |||||
<appender-ref ref="fileErrorLog"/> | |||||
</root> | |||||
</configuration> | |||||
``` |
@@ -1,24 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-logback</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-logback</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<build> | |||||
<finalName>spring-boot-demo-logback</finalName> | |||||
</build> | |||||
</project> |
@@ -1,27 +0,0 @@ | |||||
package com.xkcoding.springbootdemologback; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
import org.springframework.context.ConfigurableApplicationContext; | |||||
@SpringBootApplication | |||||
@Slf4j | |||||
public class SpringBootDemoLogbackApplication { | |||||
public static void main(String[] args) { | |||||
ConfigurableApplicationContext context = SpringApplication.run(SpringBootDemoLogbackApplication.class, args); | |||||
int length = context.getBeanDefinitionNames().length; | |||||
log.trace("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.debug("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.info("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.warn("Spring boot启动初始化了 {} 个 Bean", length); | |||||
log.error("Spring boot启动初始化了 {} 个 Bean", length); | |||||
try { | |||||
int i = 0; | |||||
int j = 1 / i; | |||||
} catch (Exception e) { | |||||
log.error("【SpringBootDemoLogbackApplication】启动异常:", e); | |||||
} | |||||
} | |||||
} |
@@ -1,6 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
application: | |||||
name: logback-demo |
@@ -1,49 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8" ?> | |||||
<configuration> | |||||
<conversionRule conversionWord="clr" | |||||
converterClass="org.springframework.boot.logging.logback.ColorConverter"/> | |||||
<conversionRule conversionWord="wex" | |||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> | |||||
<conversionRule conversionWord="wEx" | |||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> | |||||
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> | |||||
<layout class="ch.qos.logback.classic.PatternLayout"> | |||||
<pattern>【xkcoding】%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} | |||||
</pattern> | |||||
</layout> | |||||
</appender> | |||||
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<!--滚动策略--> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<!--输出路径--> | |||||
<fileNamePattern>${user.dir}/logs/log/logback-demo.%d.log</fileNamePattern> | |||||
</rollingPolicy> | |||||
<encoder> | |||||
<pattern>【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern> | |||||
</encoder> | |||||
</appender> | |||||
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||||
<level>ERROR</level> | |||||
<onMatch>ACCEPT</onMatch> | |||||
<onMismatch>DENY</onMismatch> | |||||
</filter> | |||||
<!--滚动策略--> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<!--输出路径--> | |||||
<fileNamePattern>${user.dir}/logs/error/logback-demo.%d.error</fileNamePattern> | |||||
</rollingPolicy> | |||||
<encoder> | |||||
<pattern>【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern> | |||||
</encoder> | |||||
</appender> | |||||
<root level="info"> | |||||
<appender-ref ref="consoleLog"/> | |||||
<appender-ref ref="fileLog"/> | |||||
<appender-ref ref="fileErrorLog"/> | |||||
</root> | |||||
</configuration> |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemologback; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoLogbackApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,193 +0,0 @@ | |||||
# spring-boot-demo-orm-jdbctemplate | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、spring-boot-starter-jdbc | |||||
## pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-orm-jdbctemplate</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-orm-jdbctemplate</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-jdbc</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>druid-spring-boot-starter</artifactId> | |||||
<version>1.1.9</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-orm-jdbctemplate</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
## application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
datasource: | |||||
# 启动时自动运行的 SQL 文件 | |||||
schema: classpath:init-sql/schema.sql | |||||
continue-on-error: true | |||||
druid: | |||||
url: jdbc:mysql://localhost:3306/spring-boot-demo?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false | |||||
username: root | |||||
password: root | |||||
driver-class-name: com.mysql.jdbc.Driver | |||||
# 连接池配置 | |||||
# 初始化大小,最小,最大 | |||||
initialSize: 5 | |||||
minIdle: 5 | |||||
maxActive: 20 | |||||
# 配置获取连接等待超时的时间 | |||||
maxWait: 60000 | |||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||||
timeBetweenEvictionRunsMillis: 60000 | |||||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||||
minEvictableIdleTimeMillis: 300000 | |||||
validationQuery: SELECT 1 FROM DUAL | |||||
testWhileIdle: true | |||||
testOnBorrow: false | |||||
testOnReturn: false | |||||
# 打开PSCache,并且指定每个连接上PSCache的大小 | |||||
poolPreparedStatements: true | |||||
maxPoolPreparedStatementPerConnectionSize: 20 | |||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 | |||||
filters: stat,wall,log4j | |||||
# 监控配置 | |||||
web-stat-filter: | |||||
enabled: true | |||||
url-pattern: /* | |||||
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" | |||||
stat-view-servlet: | |||||
enabled: true | |||||
url-pattern: /sys/druid/* | |||||
reset-enable: fasle | |||||
login-username: xkcoding | |||||
login-password: 123456 | |||||
filter: | |||||
stat: | |||||
log-slow-sql: true | |||||
slow-sql-millis: 5000 | |||||
merge-sql: true | |||||
``` | |||||
## schema.sql | |||||
```mysql | |||||
SET FOREIGN_KEY_CHECKS=0; | |||||
DROP TABLE IF EXISTS `jdbctemplate_user`; | |||||
CREATE TABLE `jdbctemplate_user` ( | |||||
`id` int(11) NOT NULL AUTO_INCREMENT, | |||||
`name` varchar(32) DEFAULT NULL, | |||||
`tel` varchar(11) DEFAULT NULL, | |||||
`create_time` datetime DEFAULT NULL, | |||||
PRIMARY KEY (`id`) | |||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |||||
INSERT INTO `jdbctemplate_user` VALUES (1, 'klay', '13799008800', '2017-11-13 16:04:39'); | |||||
INSERT INTO `jdbctemplate_user` VALUES (2, 'Tome', '18988991234', '2017-11-13 16:13:28'); | |||||
``` | |||||
## UserServiceImpl.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* UserServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.service.impl | |||||
* @description: UserServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:27 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
public class UserServiceImpl implements UserService { | |||||
@Autowired | |||||
private JdbcTemplate jdbcTemplate; | |||||
@Override | |||||
public Integer save(User user) { | |||||
String sql = "INSERT INTO jdbctemplate_user (name,tel,create_time) VALUES(?,?,?)"; | |||||
return jdbcTemplate.update(sql, user.getName(), user.getTel(), user.getCreateTime()); | |||||
} | |||||
@Override | |||||
public Integer update(User user) { | |||||
String sql = "UPDATE jdbctemplate_user SET name = ?,tel = ? where id = ?"; | |||||
return jdbcTemplate.update(sql, user.getName(), user.getTel(), user.getId()); | |||||
} | |||||
@Override | |||||
public Integer delete(User user) { | |||||
String sql = "DELETE FROM jdbctemplate_user where id = ?"; | |||||
return jdbcTemplate.update(sql, user.getId()); | |||||
} | |||||
@Override | |||||
public User findById(Integer id) { | |||||
String sql = "SELECT * FROM jdbctemplate_user where id = ?"; | |||||
RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class); | |||||
return jdbcTemplate.queryForObject(sql, new Object[]{id}, rowMapper); | |||||
} | |||||
@Override | |||||
public User findByName(String name) { | |||||
String sql = "SELECT * FROM jdbctemplate_user where name = ?"; | |||||
RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class); | |||||
return jdbcTemplate.queryForObject(sql, new Object[]{name}, rowMapper); | |||||
} | |||||
@Override | |||||
public List<User> findAll() { | |||||
String sql = "SELECT * FROM jdbctemplate_user"; | |||||
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql); | |||||
List<User> ret = Lists.newArrayList(); | |||||
maps.forEach(map -> ret.add(BeanUtil.fillBeanWithMap(map, new User(), true, false))); | |||||
return ret; | |||||
} | |||||
@Override | |||||
public List<User> findUserByPage(Integer pageNum, Integer pageSize) { | |||||
String sql = "SELECT * FROM jdbctemplate_user LIMIT ?,?"; | |||||
Integer offset = (pageNum - 1) * pageSize; | |||||
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{offset, pageSize}); | |||||
List<User> ret = Lists.newArrayList(); | |||||
maps.forEach(map -> ret.add(BeanUtil.fillBeanWithMap(map, new User(), true, false))); | |||||
return ret; | |||||
} | |||||
} | |||||
``` | |||||
## 其余代码 | |||||
详情请参见本demo。 |
@@ -1,36 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-orm-jdbctemplate</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-orm-jdbctemplate</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||||
</parent> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-jdbc</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>druid-spring-boot-starter</artifactId> | |||||
<version>1.1.9</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-orm-jdbctemplate</finalName> | |||||
</build> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoOrmJdbctemplateApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoOrmJdbctemplateApplication.class, args); | |||||
} | |||||
} |
@@ -1,94 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate.controller; | |||||
import com.xiaoleilu.hutool.util.StrUtil; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.model.User; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.service.UserService; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.vo.R; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* UserController | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.controller | |||||
* @description: UserController | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:52 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
public class UserController { | |||||
@Autowired | |||||
private UserService userService; | |||||
@GetMapping("/save") | |||||
public R save() { | |||||
User user = new User(); | |||||
user.setName("xkcoding"); | |||||
user.setTel("18600000000"); | |||||
user.setCreateTime(new Date()); | |||||
Integer save = userService.save(user); | |||||
if (save > 0) { | |||||
return R.builder().code(200).msg("添加成功").data(user).build(); | |||||
} | |||||
return R.builder().code(500).msg("添加失败").data(null).build(); | |||||
} | |||||
@GetMapping("/update") | |||||
public R update() { | |||||
User user = new User(); | |||||
user.setId(2); | |||||
user.setName(" 修改后的名字 "); | |||||
user.setTel("17300000000"); | |||||
Integer update = userService.update(user); | |||||
if (update > 0) { | |||||
return R.builder().code(200).msg("修改成功").data(userService.findById(2)).build(); | |||||
} | |||||
return R.builder().code(500).msg("修改失败").data(null).build(); | |||||
} | |||||
@GetMapping("/delete") | |||||
public R delete() { | |||||
User user = new User(); | |||||
user.setId(1); | |||||
Integer delete = userService.delete(user); | |||||
if (delete > 0) { | |||||
return R.builder().code(200).msg("删除成功").data(null).build(); | |||||
} | |||||
return R.builder().code(500).msg("删除失败").data(null).build(); | |||||
} | |||||
@GetMapping("/find/{id}") | |||||
public R findById(@PathVariable Integer id) { | |||||
User user = userService.findById(id); | |||||
return R.builder().code(user == null ? 404 : 200).msg(user == null ? StrUtil.format("没有ID为{}的用户", id) : "查询成功").data(user).build(); | |||||
} | |||||
@GetMapping("/find") | |||||
public R findByName(@RequestParam String name) { | |||||
User user = userService.findByName(name); | |||||
return R.builder().code(user == null ? 404 : 200).msg(user == null ? StrUtil.format("没有姓名为{}的用户", name) : "查询成功").data(user).build(); | |||||
} | |||||
@GetMapping({"", "/"}) | |||||
public R findAll() { | |||||
List<User> userList = userService.findAll(); | |||||
return R.builder().code(userList.isEmpty() ? 404 : 200).msg(userList.isEmpty() ? "暂无用户" : "查询成功").data(userList).build(); | |||||
} | |||||
@GetMapping("/page") | |||||
public R findByPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) { | |||||
List<User> userList = userService.findUserByPage(pageNum, pageSize); | |||||
return R.builder().code(userList.isEmpty() ? 404 : 200).msg(userList.isEmpty() ? "暂无用户" : "查询成功").data(userList).build(); | |||||
} | |||||
} |
@@ -1,27 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate.model; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.util.Date; | |||||
/** | |||||
* <p> | |||||
* 实体类 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.model | |||||
* @description: 实体类 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:24 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Data | |||||
public class User implements Serializable { | |||||
private int id; | |||||
private String name; | |||||
private String tel; | |||||
private Date createTime; | |||||
} |
@@ -1,34 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate.service; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.model.User; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* UserService | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.service | |||||
* @description: UserService | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:26 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
public interface UserService { | |||||
Integer save(User user); | |||||
Integer update(User user); | |||||
Integer delete(User user); | |||||
User findById(Integer id); | |||||
User findByName(String name); | |||||
List<User> findAll(); | |||||
List<User> findUserByPage(Integer pageNum, Integer pageSize); | |||||
} |
@@ -1,84 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate.service.impl; | |||||
import com.google.common.collect.Lists; | |||||
import com.xiaoleilu.hutool.bean.BeanUtil; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.model.User; | |||||
import com.xkcoding.springbootdemoormjdbctemplate.service.UserService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.jdbc.core.BeanPropertyRowMapper; | |||||
import org.springframework.jdbc.core.JdbcTemplate; | |||||
import org.springframework.jdbc.core.RowMapper; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* <p> | |||||
* UserServiceImpl | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.service.impl | |||||
* @description: UserServiceImpl | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:27 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Service | |||||
public class UserServiceImpl implements UserService { | |||||
@Autowired | |||||
private JdbcTemplate jdbcTemplate; | |||||
@Override | |||||
public Integer save(User user) { | |||||
String sql = "INSERT INTO jdbctemplate_user (name,tel,create_time) VALUES(?,?,?)"; | |||||
return jdbcTemplate.update(sql, user.getName(), user.getTel(), user.getCreateTime()); | |||||
} | |||||
@Override | |||||
public Integer update(User user) { | |||||
String sql = "UPDATE jdbctemplate_user SET name = ?,tel = ? where id = ?"; | |||||
return jdbcTemplate.update(sql, user.getName(), user.getTel(), user.getId()); | |||||
} | |||||
@Override | |||||
public Integer delete(User user) { | |||||
String sql = "DELETE FROM jdbctemplate_user where id = ?"; | |||||
return jdbcTemplate.update(sql, user.getId()); | |||||
} | |||||
@Override | |||||
public User findById(Integer id) { | |||||
String sql = "SELECT * FROM jdbctemplate_user where id = ?"; | |||||
RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class); | |||||
return jdbcTemplate.queryForObject(sql, new Object[]{id}, rowMapper); | |||||
} | |||||
@Override | |||||
public User findByName(String name) { | |||||
String sql = "SELECT * FROM jdbctemplate_user where name = ?"; | |||||
RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class); | |||||
return jdbcTemplate.queryForObject(sql, new Object[]{name}, rowMapper); | |||||
} | |||||
@Override | |||||
public List<User> findAll() { | |||||
String sql = "SELECT * FROM jdbctemplate_user"; | |||||
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql); | |||||
List<User> ret = Lists.newArrayList(); | |||||
maps.forEach(map -> ret.add(BeanUtil.fillBeanWithMap(map, new User(), true, false))); | |||||
return ret; | |||||
} | |||||
@Override | |||||
public List<User> findUserByPage(Integer pageNum, Integer pageSize) { | |||||
String sql = "SELECT * FROM jdbctemplate_user LIMIT ?,?"; | |||||
Integer offset = (pageNum - 1) * pageSize; | |||||
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{offset, pageSize}); | |||||
List<User> ret = Lists.newArrayList(); | |||||
maps.forEach(map -> ret.add(BeanUtil.fillBeanWithMap(map, new User(), true, false))); | |||||
return ret; | |||||
} | |||||
} |
@@ -1,29 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate.vo; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
/** | |||||
* <p> | |||||
* 统一返回结果类型 | |||||
* </p> | |||||
* | |||||
* @package: com.xkcoding.springbootdemoormjdbctemplate.vo | |||||
* @description: 统一返回结果类型 | |||||
* @author: yangkai.shen | |||||
* @date: Created in 2018/5/11 下午3:53 | |||||
* @copyright: Copyright (c) 2018 | |||||
* @version: V1.0 | |||||
* @modified: yangkai.shen | |||||
*/ | |||||
@Data | |||||
@NoArgsConstructor | |||||
@AllArgsConstructor | |||||
@Builder | |||||
public class R { | |||||
private int code; | |||||
private String msg; | |||||
private Object data; | |||||
} |
@@ -1,49 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
datasource: | |||||
# 启动时自动运行的 SQL 文件 | |||||
schema: classpath:init-sql/schema.sql | |||||
continue-on-error: true | |||||
druid: | |||||
url: jdbc:mysql://localhost:3306/spring-boot-demo?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false | |||||
username: root | |||||
password: root | |||||
driver-class-name: com.mysql.jdbc.Driver | |||||
# 连接池配置 | |||||
# 初始化大小,最小,最大 | |||||
initialSize: 5 | |||||
minIdle: 5 | |||||
maxActive: 20 | |||||
# 配置获取连接等待超时的时间 | |||||
maxWait: 60000 | |||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||||
timeBetweenEvictionRunsMillis: 60000 | |||||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||||
minEvictableIdleTimeMillis: 300000 | |||||
validationQuery: SELECT 1 FROM DUAL | |||||
testWhileIdle: true | |||||
testOnBorrow: false | |||||
testOnReturn: false | |||||
# 打开PSCache,并且指定每个连接上PSCache的大小 | |||||
poolPreparedStatements: true | |||||
maxPoolPreparedStatementPerConnectionSize: 20 | |||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 | |||||
filters: stat,wall,log4j | |||||
# 监控配置 | |||||
web-stat-filter: | |||||
enabled: true | |||||
url-pattern: /* | |||||
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" | |||||
stat-view-servlet: | |||||
enabled: true | |||||
url-pattern: /sys/druid/* | |||||
reset-enable: fasle | |||||
login-username: xkcoding | |||||
login-password: 123456 | |||||
filter: | |||||
stat: | |||||
log-slow-sql: true | |||||
slow-sql-millis: 5000 | |||||
merge-sql: true |
@@ -1,13 +0,0 @@ | |||||
SET FOREIGN_KEY_CHECKS=0; | |||||
DROP TABLE IF EXISTS `jdbctemplate_user`; | |||||
CREATE TABLE `jdbctemplate_user` ( | |||||
`id` int(11) NOT NULL AUTO_INCREMENT, | |||||
`name` varchar(32) DEFAULT NULL, | |||||
`tel` varchar(11) DEFAULT NULL, | |||||
`create_time` datetime DEFAULT NULL, | |||||
PRIMARY KEY (`id`) | |||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |||||
INSERT INTO `jdbctemplate_user` VALUES (1, 'klay', '13799008800', '2017-11-13 16:04:39'); | |||||
INSERT INTO `jdbctemplate_user` VALUES (2, 'Tome', '18988991234', '2017-11-13 16:13:28'); |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjdbctemplate; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoOrmJdbctemplateApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,148 +0,0 @@ | |||||
# spring-boot-demo-jpa | |||||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-data-jpa`、`druid-spring-boot-starter` | |||||
### pom.xml | |||||
```xml | |||||
<?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> | |||||
<artifactId>spring-boot-demo-orm-jpa</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-orm-jpa</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<druid.starter.version>1.1.5</druid.starter.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-data-jpa</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>druid-spring-boot-starter</artifactId> | |||||
<version>${druid.starter.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-orm-jpa</finalName> | |||||
</build> | |||||
</project> | |||||
``` | |||||
### application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
context-path: /demo | |||||
spring: | |||||
datasource: | |||||
continue-on-error: true | |||||
druid: | |||||
url: jdbc:mysql://localhost:3306/spring-boot-demo?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false | |||||
username: root | |||||
password: root | |||||
driver-class-name: com.mysql.jdbc.Driver | |||||
# 连接池配置 | |||||
# 初始化大小,最小,最大 | |||||
initialSize: 5 | |||||
minIdle: 5 | |||||
maxActive: 20 | |||||
# 配置获取连接等待超时的时间 | |||||
maxWait: 60000 | |||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||||
timeBetweenEvictionRunsMillis: 60000 | |||||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||||
minEvictableIdleTimeMillis: 300000 | |||||
validationQuery: SELECT 1 FROM DUAL | |||||
testWhileIdle: true | |||||
testOnBorrow: false | |||||
testOnReturn: false | |||||
# 打开PSCache,并且指定每个连接上PSCache的大小 | |||||
poolPreparedStatements: true | |||||
maxPoolPreparedStatementPerConnectionSize: 20 | |||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 | |||||
filters: stat,wall,log4j | |||||
# 监控配置 | |||||
web-stat-filter: | |||||
enabled: true | |||||
url-pattern: /* | |||||
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" | |||||
stat-view-servlet: | |||||
enabled: true | |||||
url-pattern: /sys/druid/* | |||||
reset-enable: fasle | |||||
login-username: xkcoding | |||||
login-password: 123456 | |||||
filter: | |||||
stat: | |||||
log-slow-sql: true | |||||
slow-sql-millis: 5000 | |||||
merge-sql: true | |||||
jpa: | |||||
hibernate: | |||||
ddl-auto: create-drop | |||||
show-sql: true | |||||
``` | |||||
### JpaUser.java | |||||
```java | |||||
@Entity | |||||
@Data | |||||
@DynamicUpdate | |||||
public class JpaUser { | |||||
@Id | |||||
@GeneratedValue(strategy = GenerationType.IDENTITY) | |||||
private Long id; | |||||
@Column(name = "name") | |||||
private String name; | |||||
@Column(name = "create_time") | |||||
private Date createTime; | |||||
} | |||||
``` | |||||
### JpaUserRepository.java | |||||
```java | |||||
public interface JpaUserRepository extends JpaRepository<JpaUser, Long> { | |||||
/** | |||||
* 自定义一个查询,HQL,根据姓名查询 | |||||
* | |||||
* @param name 名称 | |||||
* @return JpaUser | |||||
*/ | |||||
@Query("from JpaUser u where u.name like :name") | |||||
JpaUser findJpaUser(@Param("name") String name); | |||||
JpaUser findJpaUserByName(String name); | |||||
List<JpaUser> findJpaUsersByIdIn(List<Long> ids); | |||||
} | |||||
``` | |||||
### 其余代码 | |||||
详情请参见本demo。 |
@@ -1,40 +0,0 @@ | |||||
<?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> | |||||
<artifactId>spring-boot-demo-orm-jpa</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-orm-jpa</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo-parent</artifactId> | |||||
<version>0.0.1-SNAPSHOT</version> | |||||
<relativePath>../spring-boot-demo-parent</relativePath> | |||||
</parent> | |||||
<properties> | |||||
<druid.starter.version>1.1.5</druid.starter.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-data-jpa</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>druid-spring-boot-starter</artifactId> | |||||
<version>${druid.starter.version}</version> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-orm-jpa</finalName> | |||||
</build> | |||||
</project> |
@@ -1,12 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjpa; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
@SpringBootApplication | |||||
public class SpringBootDemoOrmJpaApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoOrmJpaApplication.class, args); | |||||
} | |||||
} |
@@ -1,86 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjpa.controller; | |||||
import com.google.common.collect.Lists; | |||||
import com.xkcoding.springbootdemoormjpa.entity.JpaUser; | |||||
import com.xkcoding.springbootdemoormjpa.service.JpaUserService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.data.domain.Page; | |||||
import org.springframework.data.domain.PageRequest; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
public class JpaUserController { | |||||
@Autowired | |||||
private JpaUserService jpaUserService; | |||||
@GetMapping("/{id}") | |||||
public JpaUser findById(@PathVariable Long id) { | |||||
return jpaUserService.findById(id); | |||||
} | |||||
@GetMapping({"", "/", "/index"}) | |||||
public List<JpaUser> findAll() { | |||||
return jpaUserService.findAll(); | |||||
} | |||||
@GetMapping("/save") | |||||
public JpaUser insert() { | |||||
JpaUser user = new JpaUser(); | |||||
user.setName("xkcoding"); | |||||
user.setCreateTime(new Date()); | |||||
return jpaUserService.insert(user); | |||||
} | |||||
@GetMapping("/update") | |||||
public JpaUser update() { | |||||
JpaUser user = jpaUserService.findById(1L); | |||||
user.setName("修改后的姓名"); | |||||
return jpaUserService.update(user); | |||||
} | |||||
@GetMapping("/delete/{id}") | |||||
public String delete(@PathVariable Integer id) { | |||||
if (id == null) { | |||||
return "Id 不能为空"; | |||||
} | |||||
JpaUser jpaUser = jpaUserService.findById(id.longValue()); | |||||
if (jpaUser == null) { | |||||
return "用户不存在"; | |||||
} | |||||
jpaUserService.delete(jpaUser); | |||||
return jpaUser.getName() + "删除成功"; | |||||
} | |||||
@GetMapping("/saveList") | |||||
public List<JpaUser> insertList() { | |||||
List<JpaUser> userList = Lists.newArrayList(); | |||||
for (int i = 0; i < 20; i++) { | |||||
JpaUser jpaUser = new JpaUser(); | |||||
jpaUser.setName("xkcoding" + i); | |||||
jpaUser.setCreateTime(new Date()); | |||||
userList.add(jpaUser); | |||||
} | |||||
return jpaUserService.insertList(userList); | |||||
} | |||||
@GetMapping("/find") | |||||
public JpaUser findJpaUser(@RequestParam String name) { | |||||
return jpaUserService.findJpaUser(name); | |||||
} | |||||
@GetMapping("/find/in") | |||||
public List<JpaUser> findJpaUsersByIdIn() { | |||||
List<Long> ids = Lists.newArrayList(1L, 2L, 3L); | |||||
return jpaUserService.findJpaUsersByIdIn(ids); | |||||
} | |||||
@GetMapping("/page") | |||||
public Page<JpaUser> findByPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { | |||||
PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize); | |||||
return jpaUserService.findByPage(pageRequest); | |||||
} | |||||
} |
@@ -1,22 +0,0 @@ | |||||
package com.xkcoding.springbootdemoormjpa.entity; | |||||
import lombok.Data; | |||||
import org.hibernate.annotations.DynamicUpdate; | |||||
import javax.persistence.*; | |||||
import java.util.Date; | |||||
@Entity | |||||
@Data | |||||
@DynamicUpdate | |||||
public class JpaUser { | |||||
@Id | |||||
@GeneratedValue(strategy = GenerationType.IDENTITY) | |||||
private Long id; | |||||
@Column(name = "name") | |||||
private String name; | |||||
@Column(name = "create_time") | |||||
private Date createTime; | |||||
} |