什么是spring boot

  Spring Boot是一个简化Spring开发的框架。用来监护spring应用开发,约定大于配置,去繁就简,just run 就能创建一个独立的,产品级的应用。
  我们在使用Spring Boot时只需要配置相应的Spring Boot就可以用所有的Spring组件,简单的说,spring boot就是整合了很多优秀的框架,不用我们自己手动的去写一堆xml配置然后进行配置。从本质上来说,Spring Boot就是Spring,它做了那些没有它你也会去做的Spring Bean配置。

单体应用与微服务

  单体应用是把所有的应用模块都写在一个应用中,导致项目越写越大,模块之间的耦合度也会越来越高。微服务是一种架构风格,用微服务可以将应用的模块单独部署,对不同的模块进行不同的管理操作,不同的模块生成小型服务,每个功能元素最后都可以成为一个可以独立替换、独立升级的功能单元,各个小型服务之间通过http进行通信。

核心特点

  微服务:使用Spring Boot可以生成独立的微服务功能单元。
  自动配置:针对很多Spring应用程序常见的应用功能,Spring Boot能自动提供相关配置。
  起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库。

项目

用maven构建项目

  其实使用maven或gradle、ant构建都是可以的,使用maven比较熟。
  Maven使用基于XML的配置,Gradle采用了领域特定语言Groovy的配置。

配置pom.xml

  Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter 相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?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.sinosoft</groupId>
<artifactId>blacklist-platform</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>blacklist-platform</name>
<description>Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version><!-- 2.x版本,外置tomcat版本需要用8以上的 -->
</parent>
<!-- Spring Boot的版本仲裁中心;以后我们导入依赖默认是不需要写版本。(没有在dependencies里面管理的依赖自然需要声明版本号) -->
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<druid.version>1.1.9</druid.version>
<snakeyaml.version>1.19</snakeyaml.version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<!-- tomcat -->
<dependency>
<!-- 移除嵌入式tomcat插件 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作-->
<scope>provided</scope>
</dependency>

<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<!-- activemq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

<!-- alibaba的一个高效连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>

<!-- spring框架下的mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>

<!-- mysql连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<!-- dubbo,不是官方dubbo-spring-boot-starter -->
<dependency>
<groupId>com.gitee.reger</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.1.1</version>
</dependency>

<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>

<!-- 工具包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
<build>
<finalName>blacklist-platform</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

application.yml

1
2
3
4
spring:
# 读取哪个配置
profiles:
active: dev

application-dev.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
server:
port: 9999
mybatis:
type-aliases-package: com.sinosoft.application.model
mapper-locations: classpath:mapper/*.xml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://xxx.xx.xx.xx:3306/xxxdb?useUnicode=true&characterEncoding=utf-8
username: xxx
password: xxxx
driver-class-name: com.mysql.jdbc.Driver
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
useGlobalDataSourceStat: true
activemq:
broker-url: failover:(tcp://xxx.xxx.xxx.xxx:61616,tcp://xxx.xx.xx.xx:61616)
user: admin
password: admin
pool:
enabled: true
max-connections: 50
expiry-timeout: 10000
idle-timeout: 30000
dubbo:
application:
name: blacklist-platform
registry:
address: zookeeper://xxx.xxx.xxx.xxx:2181?xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181
scan: com.sinosoft.blacklist.service

启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@SpringBootApplication //代表springboot的启动类 用来标注主程序类 说明是一个springboot应用
@ServletComponentScan("com.sinosoft.blacklist.servlet") //扫描servlet
@MapperScan("com.sinosoft.blacklist.dao") //扫描mapper
@ComponentScan(basePackages= {"com.sinosoft.blacklist.service","com.sinosoft.blacklist.controller"}) //扫描bean 包含@Component的注解,有@Component,@service,@controller,@Repository,@Configuration
@EnableScheduling
public class ApplicationRun extends SpringBootServletInitializer{

public static void main(String[] args) {
SpringApplication.run(ApplicationRun.class, args); //springboot启动类
}

//如使用外置tomcat,必须继承SpringBootServletInitializer,并重写configure方法,因为没有web.xml,tomcat无法进行加载,也无法知道入口,这个类就是暴露入口给tomcat。使用外置tomcat,yml中配置的port,ip会被忽略,使用tomcat下的service.xml中的配置。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ApplicationRun.class);
}
}

service

1
2
3
4
5
6
7
8
9
@Service
public class BlackListServiceImpl implements BlackListService{

@Override
public String demo() {
return BlackListServiceImpl.class.toString();
}

}

contoller

  实质是servlet,由DispatcherServlet分发请求。

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class BlackListController {
private Logger logger = LoggerFactory.getLogger(BlackListController.class);

@Autowired
private BlackListService blackListService;

@RequestMapping("/")
public String welcome() {
resp.getWriter().append(blackListService.demo());
}
}

servlet

  在springboot中servlet,想要调用spring中的bean,需要实现public void init(ServletConfig config) throws ServletException;方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@WebServlet(urlPatterns = "/BlackListServlet")
public class BlackListServlet extends HttpServlet {

private static final long serialVersionUID = 7001557094255066523L;
private static Logger logger = Logger.getLogger(BlackListServlet.class);

@Autowired
private BlackListService blackListService;

@Override
public void init(ServletConfig config) throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().append(blackListService.demo());
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doRun(req, resp);
}

private void doRun(HttpServletRequest req, HttpServletResponse resp) {
try {
req.getSession().setMaxInactiveInterval(120);
BufferedReader br = new BufferedReader(
new InputStreamReader((ServletInputStream) req.getInputStream(), "utf-8"));
System.out.println("BlackListServlet======================begin");
logger.info("BlackListServlet======================begin");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json; charset=utf-8");
StringBuilder sb = new StringBuilder();
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
System.out.println(sb.toString());
logger.info(sb.toString());

System.out.println("BlackListServlet======================end");
logger.info("BlackListServlet======================end");
} catch (Exception e) {
e.printStackTrace();
}
}
}