SpringBoot入门
最近公司很多项目都在改版,都统一往SpringBoot上迁移,刚好最近一段时间手头上事情没那么多,抽时间学习一下
首先了解下啥是微服务
以前最早接触的是SOA架构,这个提出的也是微服务的概念,个人理解微服务就好比是把一个大的功能多而全的系统拆分成一个个功能独立,互不影响,但可能业务上有关联的子系统,说白了就是功能模块拆分,独立运行,然后通过内部通信或者工作流串联在一起
导入项目以及相关配置
1、项目原型地址:http://start.spring.io/,下载完后直接导入项目
2、在下用的是IDEA,如果用的是eclipse的话,直接以maven项目导入即可
3、pom配置(这里直接把数据库还有单元测试的相关依赖都引入进来了):
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo Demo Demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
4、application.properties文件相关配置
数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
这里用的是JPA,如果需要用其他如hibernate、mybatis配置的,换成对应的配置就行
thymelea模板配置
#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
#热部署文件,页面不产生缓存,及时更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.static-locations = classpath:/templates/
spring.devtools.restart.enabled=true
开发过程中发现无法引入js和css的问题,这里就需要关注 spring.resources.static-locations这个配置了,这个配置是声明一些静态文件的默认访问地址
Redis相关配置
# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
## Redis服务器地址
spring.redis.host=127.0.0.1
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=-1
## 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
## 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
## 连接超时时间(毫秒)
spring.redis.timeout=5000
##redis缓存对象过期单位: 0表示秒,1表示分,2表示小时,3表示天
redis.session.unit=1
##redis缓存对象过期时间
redis.session.timeout=10
redis.session.unit和redis.session.timeout这两个配置我自己添加的,目的是为了设置redis缓存的有效期
接下来的就是具体的代码实现了,这里实现是一个简单例子
实体类
@Table(name="t_user")
@Entity
public class User implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
@Column(name="name",nullable = false, unique = true)
private String name;
@Column(name="password",nullable = false)
private String password;
@Column(name="telephone",nullable = true, unique = true)
private String telephone;
@Column(name="email",nullable = false, unique = true)
private String email;
@Column(name="sex",nullable = false)
private String sex;
@Column(name="age",nullable = false)
private int age;
@Column(name="nickname",nullable = false, unique = true)
private String nickName;
@Column(name="createtime",nullable = false)
private String createTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
这里就不多说了,有一个提下,最近有看到Lombok这个东东,项目引入这个jar后,不用写那么多的get和set方法了,可以直接注解实现 @Getter、@Setter ,这个东西只是稍微了解了下,没怎么深入使用,有兴趣的可以学习下
地址:https://projectlombok.org/download
Maven依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
Dao层
public interface UserRepository extends JpaRepository<User,Long> {
User findUserByName(String name);
User findUserByNickName(String nickName);
Page<User> findAll(Pageable pageable);
@Transactional
@Query("select u from User u where u.sex = ?1")
List<User> findBySex(String sex);
@Transactional
@Query("select u from User u where u.id = ?1")
User findById(int id);
@Query("select u from User u where u.nickName = ?1 and u.password=?2")
User findUserByNameAndPwd(String nickName, String password);
}
Service层
public interface UserService {
User findUserById(int id);
User findUserByName(String name);
User findUserByNickName(String nickName);
Page<User> findAll(Pageable pageable);
List<User> findBySex(String sex);
List<User> findAllUser();
User saveUser(User user);
void updateUser(User user);
User findUserByNameAndPwd(String nickName, String password);
}
Service实现类:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User findUserByName(String name) {
return userRepository.findUserByName(name);
}
@Override
public User findUserByNickName(String nickName) {
return userRepository.findUserByNickName(nickName);
}
@Override
public Page<User> findAll(Pageable pageable) {
return userRepository.findAll(pageable);
}
@Override
public List<User> findBySex(String sex) {
return userRepository.findBySex(sex);
}
@Override
public User saveUser(User user) {
return userRepository.save(user);
}
@Override
public List<User> findAllUser() {
return userRepository.findAll();
}
@Override
public User findUserById(int id) {
return userRepository.findById(id);
}
@Override
public void updateUser(User user) {
userRepository.save(user);
}
@Override
public User findUserByNameAndPwd(String nickName, String password) {
return userRepository.findUserByNameAndPwd(nickName,password);
}
}
业务层Controller
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(ModelMap map){
map.put("loginForm",new LoginForm());
return "/login";
}
@RequestMapping("/authenticate")
public String authenticate(@ModelAttribute("loginForm") @Validated LoginForm form, BindingResult rs,ModelMap map){
map.put("loginForm",form);
if(rs.hasErrors()){
for (ObjectError error : rs.getAllErrors()) {
map.put("error",error.getDefaultMessage());
break;
}
return "login";
}
User user = userService.findUserByNameAndPwd(form.getUsername(),form.getPassword());
if(user == null){
map.put("error","用户名或密码错误");
return "login";
}
return "redirect:/user/list";
}
}
这里有个关于@Controller和@RestController这两个注解的不同
@Controller 方法实现直接return “xxxxxx” 即可实现跳转页面
@RestController 则需要借用ModelAndView才可实现跳转
另外,@Validated 和 BindingResult 是配套使用的,主要实现表单验证
WEB端
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Sign In</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" media="screen" th:href="@{/css/bootstrap.min.css}"/>
<link rel="stylesheet" media="screen" th:href="@{/css/core.css}" />
</head>
<body>
<form class="form-narrow form-horizontal" action="/authenticate" method="post" th:object="${loginForm}" th:action="@{/authenticate}">
<th:block th:if="${error!= null}">
<div th:replace="fragments/alert :: alert (type='danger', message=${error})">Alert</div>
</th:block>
<fieldset>
<legend>Please Sign In</legend>
<div class="form-group">
<label for="inputEmail" class="col-lg-2 control-label">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="inputEmail" placeholder="Name" name="username" th:field="*{username}" />
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<input type="password" class="form-control" id="inputPassword" placeholder="Password" name="password" th:field="*{password}" />
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<div class="checkbox">
<label>
<input type="checkbox" name="_spring_security_remember_me" /> Remember me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<p>New here? <a href="signup" th:href="@{/signup}">Sign Up</a></p>
</div>
</div>
</fieldset>
</form>
</body>
</html>
这里用的是thymeleaf官方的页面模板,直接官网地址下载即可:https://www.thymeleaf.org/download.html
以上就是一个简单的demo了