一、SpringBoot简单介绍
百度百科是这样的:
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
其他人概括是这样的:
(1)它是Spring的升级版,Spring容器能做到的事情,它都能做到,而且更简便,从配置形式上来说,SpringBoot完全抛弃了繁琐的XML文件配置方式,而是替代性地用注解方式来实现,虽然本质来说,是差不多的(类似包扫描,注解扫描,类加载之类)。
(2)SpringBoot集成的插件更多,从而使用很多服务,都只是引入一个依赖,几个注解和Java类就可以用了,具体的参考相关手册。
(3)在Web应用开发这一块,之前的应用一般来说是打包成war包,再发布到相关服务器容器下(例如Tomcat),虽然SpringBoot也可以这么做,但在SpringBoot下更常见的形式是将SpringBoot应用打包成可执行jar包文件。之所以这么做,源于你可以直接将SpringBoot应用看成是一个Java Application,其Web应用可以没有webapp目录(更不用说web.xml了),它推荐使用html页面,并将其作为静态资源使用。
二、框架搭建
(1)整体结构如下:
(2)pom文件如下所示
4.0.0
SpringBootTest
springbootdemo
1.0-SNAPSHOT
jar
spring-web-demo
demo for spring boot
org.springframework.boot
spring-boot-starter-parent
1.4.0.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-data-redis
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
mysql
mysql-connector-java
5.1.21
com.github.pagehelper
pagehelper
4.2.1
tk.mybatis
mapper
3.3.9
org.springframework.boot
spring-boot-starter-test
test
com.jayway.jsonpath
json-path
org.springframework.boot
spring-boot-maven-plugin
(3)log配置和application配置
spring.datasource.url=jdbc:mysql://localhost:3306/cqx
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
${LOG_HOME}/SpringBoot_info.log.%d{yyyy-MM-dd}.log
30
info
ACCEPT
DENY
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
10MB
${LOG_HOME}/SpringBootDemo_error.log.%d{yyyy-MM-dd}.log
30
error
ACCEPT
DENY
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
10MB
(4)建立bean类 User.class
package com.server.bean;
/**
* Created by c00415904 on 2017/9/21.
*/
public class User {
private String username;
private String userpassword;
public User(){}
public User(String username,String userpassword){
this.userpassword=userpassword;
this.username=username;
}
public String getUsername(){
return this.username;
}
public String getUserpassword(){
return this.userpassword;
}
public void setUsername(String username){
this.username=username;
}
public void setUserpassword(String password){
this.userpassword=password;
}
}
(5)数据库持久化层接口Dao 对接Mybaits,开启catch功能
package com.server.dao;
import com.server.bean.User;
import org.apache.ibatis.annotations.*;
import org.springframework.cache.annotation.Cacheable;
/**
* Created by c00415904 on 2017/9/21.
*/
@Mapper
public interface UserDao
{
@Cacheable(value = "username",key = "#p0")
@Select("select * from user_table where username = #{username}")
User findByName(@Param("username") String name);
@Insert("insert into user_table values (#{username},#{userpassword})")
int insertUser(@Param("username")String username,@Param("userpassword")String userpassword);
@Select("select count(*) from user_table")
int findCount();
@Delete("delete from user_table where username = #{username}")
int deleteByName(@Param("username") String username);
@Update("update user_table set userpassword = #{userpassword} where username= #{username}")
int updateUser(@Param("username") String username,@Param("userpassword") String userpassword);
}
(6)服务对外接口 TestInterFace 以及实现类 TestInterFaceImpl
package com.server.service.dao;
import com.server.bean.User;
import org.springframework.stereotype.Service;
/**
* Created by c00415904 on 2017/9/21.
*/
public interface TestInterFace {
public int testInterFace();
public User testUser(String username);
public int testinsertUser(String username,String userpassword);
}
package com.server.service.impl;
import com.server.bean.User;
import com.server.dao.UserDao;
import com.server.service.dao.TestInterFace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by c00415904 on 2017/9/21.
*/
@Service
public class TestInterFaceImpl implements TestInterFace {
@Autowired
private UserDao userDao;
@Override
public int testInterFace() {
return userDao.findCount();
}
@Override
public User testUser(String username) {
return userDao.findByName(username);
}
@Override
public int testinsertUser(String username, String userpassword) {
return userDao.insertUser(username,userpassword);
}
}
(7)controller类 所有的rest入口
package com.server.controller;
import com.server.bean.User;
import com.server.service.dao.TestInterFace;
import com.server.service.impl.TestInterFaceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created by c00415904 on 2017/9/21.
*/
@Controller
public class UserController {
private final Logger log = LoggerFactory.getLogger(UserController.class);
@Autowired
private TestInterFace testInterFace;
@RequestMapping("/getuser")
@ResponseBody
User getUser(@RequestParam("name") String name)
{
log.warn("Get user {}",name);
return testInterFace.testUser(name);
}
@RequestMapping("/adduser")
@ResponseBody
String addUser(String name,String password)
{
try {
log.warn("Insert user,{},{}", name, password);
if (testInterFace.testinsertUser(name, password) >= 0) {
return "ok";
} else {
return "error";
}
}catch (Exception ex){
log.error("error add user:{}",ex);
return "error";
}
}
}
package com.server.controller;
import com.server.service.dao.TestInterFace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created by c00415904 on 2017/9/21.
*/
@Controller
public class TestController
{
private final Logger log = LoggerFactory.getLogger(TestController.class);
@Autowired
private TestInterFace testInterFace;
@RequestMapping("/num")
@ResponseBody
int num()
{
log.info("get num");
return testInterFace.testInterFace();
}
}
(8)redis和mybits配置类,mybits配置未使用不做解析
package com.server.config.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import javax.print.DocFlavor;
/**
* Created by c00415904 on 2018/6/21.
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes")RedisTemplate redisTemplate){
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
//设置过期时间
cacheManager.setDefaultExpiration(10000);
return cacheManager;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
//创建一个模板类
StringRedisTemplate template = new StringRedisTemplate();
//将刚才的redis连接工厂设置到模板类中
template.setConnectionFactory(factory);
//设置序列化工具
setSerializer(template);
template.afterPropertiesSet();
return template;
}
private void setSerializer(StringRedisTemplate template){
@SuppressWarnings({"rawtypes","unchecked"})
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
}
}
(9)程序启动类
package com.server;
import com.server.config.redis.RedisConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
/**
* Created by c00415904 on 2017/9/8.
* 程序的入口
*/
@SpringBootApplication
@EnableCaching
@ComponentScan(basePackages={"com.server"})//添加的注解,扫描自动注入的接口和类
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(Application.class,args);
}
}
三、程序测试
看下程序日志:
2018-06-22 11:28:50.078 [http-nio-8080-exec-9] DEBUG o.s.boot.web.filter.OrderedRequestContextFilter - Bound request context to thread: org.apache.catalina.connector.RequestFacade@3774a2cd
2018-06-22 11:28:50.078 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing POST request for [/getuser]
2018-06-22 11:28:50.078 [http-nio-8080-exec-9] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /getuser
2018-06-22 11:28:50.079 [http-nio-8080-exec-9] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [com.server.bean.User com.server.controller.UserController.getUser(java.lang.String)]
2018-06-22 11:28:50.079 [http-nio-8080-exec-9] DEBUG o.s.b.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userController'
2018-06-22 11:28:50.079 [http-nio-8080-exec-9] WARN com.server.controller.UserController - Get user cqx5
2018-06-22 11:28:50.079 [http-nio-8080-exec-9] DEBUG o.s.data.redis.core.RedisConnectionUtils - Opening RedisConnection
2018-06-22 11:28:50.080 [http-nio-8080-exec-9] DEBUG o.s.data.redis.core.RedisConnectionUtils - Closing Redis Connection
2018-06-22 11:28:50.081 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
2018-06-22 11:28:50.081 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@45ee034e] was not registered for synchronization because synchronization is not active
2018-06-22 11:28:50.081 [http-nio-8080-exec-9] DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
2018-06-22 11:28:50.084 [http-nio-8080-exec-9] DEBUG o.m.spring.transaction.SpringManagedTransaction - JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1e4779db]]] will not be managed by Spring
2018-06-22 11:28:50.084 [http-nio-8080-exec-9] DEBUG com.server.dao.UserDao.findByName - ==> Preparing: select * from user_table where username = ?
2018-06-22 11:28:50.084 [http-nio-8080-exec-9] DEBUG com.server.dao.UserDao.findByName - ==> Parameters: cqx5(String)
2018-06-22 11:28:50.085 [http-nio-8080-exec-9] DEBUG com.server.dao.UserDao.findByName - <== Total: 1
2018-06-22 11:28:50.086 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@45ee034e]
2018-06-22 11:28:50.086 [http-nio-8080-exec-9] DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
2018-06-22 11:28:50.086 [http-nio-8080-exec-9] DEBUG o.s.data.redis.core.RedisConnectionUtils - Opening RedisConnection
2018-06-22 11:28:50.087 [http-nio-8080-exec-9] DEBUG o.s.data.redis.core.RedisConnectionUtils - Closing Redis Connection
2018-06-22 11:28:50.088 [http-nio-8080-exec-9] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.server.bean.User@7d5b8022] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@497d4c96]
2018-06-22 11:28:50.088 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2018-06-22 11:28:50.088 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
2018-06-22 11:28:50.088 [http-nio-8080-exec-9] DEBUG o.s.boot.web.filter.OrderedRequestContextFilter - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@3774a2cd
第一次的时候,redis没有缓存,所以查询了数据库,然后写入了缓存。
再运行一下查询postman,第二次测试查看日志:
只查询了redis缓存。
注意:需要启动redis服务: