Spring Boot最重要的四个核心:
Actuator有能做什么:
按照步骤,完成创建项目。
启动引导Spring
@SpringBootApplication // 开启组件扫描和自动配置
public class ReadinglistApplication {
public static void main(String[] args) {
SpringApplication.run(ReadinglistApplication.class, args); // 负责启动引导应用程序
}
}
@SpringBootApplication开启了Spring的组件扫描和Spring Boot的自动配置功能。 @SpringBootApplication将三个有用的注解组合在一起。
创建Book类
/*
*
* Created by wangxinhuang on 2018/4/18.
*/
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String reader;
private String isbn;
private String title;
private String author;
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getReader() {
return reader;
}
public void setReader(String reader) {
this.reader = reader;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
定义仓库接口
public interface ReadingListRepository extends JpaRepository {
List findByReader(String reader);
}
创建阅读列表控制器
@Controller
@RequestMapping("/")
public class ReadingListController {
@Autowired
private ReadingListRepository readingListRepository;
@GetMapping(value = "/{reader}")
public String readersBooks(@PathVariable("reader") String reader, Model model) {
List readingList = readingListRepository.findByReader(reader);
if (readingList != null) {
model.addAttribute("books", readingList);
}
return "readingList";
}
@PostMapping(value = "/{reader}")
public String addToReadingList(@PathVariable("reader") String reader, Book book) {
book.setReader(reader);
readingListRepository.save(book);
return "redirect:/{reader}";
}
}
创建Thymeleaf模板 src/resources/templates/readingList.html
阅读列表
你的阅读列表
-
标题
作者
(ISBN: ISBN)
-
描述
暂无描述
您的书架上没有书本
添加书籍
新增css样式 src/resources/static/style.css
body {
background-color: #cccccc;
}
.bookHeadline {
font-size: 12pt;
font-weight: bold;
}
.bookDescription {
font-size: 10pt;
}
label {
font-weight: bold;
}
在application.yml增加相关配置
server:
port: 8000
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3307/book?characterEncoding=UTF-8&useSSL=false
username: root
password: root
thymeleaf:
mode: HTML
encoding: UTF-8
servlet:
content-type: text/html
# 开发时关闭缓存,不然没法看到实时页面
cache: false
jpa:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
ddl-auto: update
show-sql: true
访问http://localhost:8000/test进行查看
添加spring-boot-starter-security依赖
org.springframework.boot
spring-boot-starter-security
创建读者Reader对象
@Entity
public class Reader implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
private String username;
private String fullname;
private String password;
// 授予READER权限
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("READER"));
}
// 不过期
@Override
public boolean isAccountNonExpired() {
return true;
}
// 不加锁
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
// 不禁用
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
创建ReaderRepository仓库接口
public interface ReaderRepository extends JpaRepository {
public Reader findByUsername(String username);
}
覆盖自动配置的显式安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ReaderRepository readerRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/")
.access("hasRole('READER')") // 要求登录者有READER角色
.antMatchers("/**")
.permitAll()
.and()
.formLogin()
.loginPage("/login") // 设置登录表单的路径
.failureUrl("/login?error=true");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return readerRepository.findByUsername(username);
}
});
}
}
Spring Boot应用程序有多种设置途径,能从多种属性源获得属性,包括
- 命令行参数
- java:comp/env里的JNDI属性
- JVM系统属性
- 操作系统环境变量
- 随机生成的带random.*前缀的属性
- 应用程序以外的application.properties或者application。yml文件
- 打包在应用程序内的application.properties或application。yml文件
- 通过@PropertySource标注的属性源
- 默认属性
自动配置微调
spring:
thymeleaf:
# 开发时关闭缓存,不然没法看到实时页面,生产环境要去掉
cache: false
配置日志
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log
30
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
10MB
应用程序Bean的配置外置
org.springframework.boot
spring-boot-configuration-processor
@Component
@ConfigurationProperties("amazon") // 注入带amazon前缀的属性
public class AmazonProperties {
private String associateId;
public String getAssociateId() {
return associateId;
}
public void setAssociateId(String associateId) {
this.associateId = associateId;
}
}
amazon:
associateId: habuma-20
使用Profile进行配置
spring:
profiles:
active: production
@Profile("production")
定制应用程序错误页面
错误页面
There seems to be a problem with the page you requested().
构建War文件
war
public class ReadingListServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}