Spring Boot . 4 -- 定制 Spring Boot 配置
- 覆写 Auto-Configuration 的类
- 利用外部属性进行动态配置 【本文】
- 定制 Error 页面 【第二篇】
Spring Boot的自动配置可以节省很多无趣的配置工作,但是并不是所有的自动配置都能满足需求。比如链接数据库的时候,需要使用一些OR-Mapping 的中间件;比如安全相关的配置需要针对不用的场景/应用/业务进行定制化的开发和配置;或者需要根据不同的运行时条件,做不同的分支决策;等等。所以Sping Boot 提供了两种基本方式,允许开发者对现有的自佛那个配置进行定制化的更改:配置覆写、细粒度的外部属性配置。【explicit configuration overrides、fine-grained configuration with properties】
覆写(Override)Spring Boot 的自动配置
覆写配置可以采用Spring支持的任意一种配置方式:XML、Groovy 脚本、Java 代码 等。这里使用Java代码方式的配置。WebSecurityConfigurerAdapter 提供了覆写SecurityConfig 的入口。做这样的假定:(1)只在登录页面做登录校验,其他页面不进行校验;(2)登陆账户和密码是 user-password;(3)登录这的角色为 USER。
首先定义一个Controller响应Http请求。响应登录、查看登录状态、登出 等Http请求。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class HelloController { @Autowired
private ReaderRepository readerRepository; @RequestMapping(value = "/addUser")
public String addUser()
{
// 向数据库中加入一个User
Reader reader = new Reader();
reader.setFullname("pa");
reader.setPassword("password");
reader.setUsername("user");
readerRepository.save(reader);
return "index";
} @RequestMapping("/")
public String index() {
readerRepository.saveAndFlush(new Reader("user","password","password"));
return "index";
} @RequestMapping("/hello")
public String hello() {
return "hello";
} @RequestMapping("/login")
public String login() {
return "login";
}
}
实现自主配置的 安全校验是通过 继承和覆写 WebSecurityConfiguerAdapter 类来实现的,指定需要进行安全校验的类,指定进行校验的数据等,代码如下:
package readinglist; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; @Configuration
@EnableWebSecurity // 这个注解启用了定制的安全配置 安全的校验机制按照被注解类的逻辑进行
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired
private ReaderRepository readerRepository; @Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll() // "/" 这个路径下不进行安全校验
.anyRequest().authenticated() // 其他的路径均需要校验
.and()
.formLogin()
.loginPage("/login") // 默认的登录页面
.permitAll()
.and()
.logout()
.permitAll();
}
// 在这里进行登录校验,通过数据库来进行 用户名和密码的 校验
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
return readerRepository.findOne(username);
}
});
} public void setReaderRepository(ReaderRepository readerRepository) {
this.readerRepository = readerRepository;
}
}
以上就是最核心的代码。其他的自主配置的方式基本一致。
辅助的代码:Reader 的定义。
package readinglist; import java.util.Arrays;
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; @Entity
public class Reader implements UserDetails {
private static final long serialVersionUID = 1L; @Id
public String username;
public String fullname;
public String password; @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
@Override
public boolean isAccountNonExpired() {
return true;
} @Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Repository 的代码:
package readinglist;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ReaderRepository extends JpaRepository<Reader, String> {
}
Spring Boot . 4 -- 定制 Spring Boot 配置的更多相关文章
- Spring Boot . 4 -- 定制 Spring Boot 配置 【2】
除了第一篇中使用 覆写的方式进行 自动配置的更改外,还可以通过 Spring Boot 中提供的 application.properties 文件改变应用的运行时配置.这种配置的方式粒度是非常精细的 ...
- Spring Boot实践——基础和常用配置
借鉴:https://blog.csdn.net/j903829182/article/details/74906948 一.Spring Boot 启动注解说明 @SpringBootApplica ...
- 自定义的Spring Boot starter如何设置自动配置注解
本文首发于个人网站: 在Spring Boot实战之定制自己的starter一文最后提到,触发Spring Boot的配置过程有两种方法: spring.factories:由Spring Boot触 ...
- Spring Boot源码探索——自动配置的内部实现
前面写了两篇文章 <Spring Boot自动配置的魔法是怎么实现的>和 <Spring Boot起步依赖:定制starter>,分别分析了Spring Boot的自动配置和起 ...
- Spring Boot使用Druid和监控配置
Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource 整体步骤: (1) -- Druid简单介绍,具体看官网: (2) ...
- Spring Boot应用的后台运行配置
酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: 运行Spring Boot的应用主类 使用Mave ...
- Spring boot 的 properties 属性值配置 application.properties 与 自定义properties
配置属性值application.properties 文件直接配置: com.ieen.super.name="MDD" 自定义properties文件配置:src/main/r ...
- Spring Boot 启动(二) 配置详解
Spring Boot 启动(二) 配置详解 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Boot 配置 ...
- Spring Boot 中使用 @Transactional 注解配置事务管理
事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...
随机推荐
- cmath函数整理
double a= pow(double x, double y)://返回x的y次方. double a= sqrt(double x)://返回x的平方根. double a=ceil(doubl ...
- 在使用react时的异步问题解决
在时用react时, 常常会出现在创建一个对象后, 对象还没有创建完成就被使用的异步问题, 介于这种问题, 一种解决方法就是使用Promise, 将需要被等待的那一步放到Promise中, Promi ...
- ES6躬行记(23)——Promise的静态方法和应用
一.静态方法 Promise有四个静态方法,分别是resolve().reject().all()和race(),本节将着重分析这几个方法的功能和特点. 1)Promise.resolve() 此方法 ...
- .NET Core 跨平台物联网开发:SDK 属性、方法、委托、类(四)
系列教程目录 (一) 连接阿里云IOT (二) 设置委托事件 (三) 上报属性 (四) SDK文档 属性.方法.委托.类 http://pan.whuanle.cn/index.php?dir=up ...
- codeforces 570 D. Tree Requests (dfs)
题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...
- Frequency of String CodeForces - 963D
http://codeforces.com/contest/963/problem/D 题解:https://www.cnblogs.com/Blue233333/p/8881614.html 记M为 ...
- AsyncTask官方教程-推荐用AsyncTask少用Thread
Using AsyncTask AsyncTask allows you to perform asynchronous work on your user interface. It perform ...
- c#如何使用replace函数将"\"替换成"\\"
当我使用 String str="c:\aa.xls"; str=str.Replace("\","\\");时,括号为红色错误的,那么如何 ...
- TestNG基本注解(一)
TestNG基本注解 注解 描述 @BeforeSuite 注解的方法将只运行一次,运行所有测试前此套件中. @AfterSuite 注解的方法将只运行一次此套件中的所有测试都运行之后. @Bef ...
- Mybatis查询select操作
先看select标签的属性: 说几点: resultType和resultMap都是用来表示结果集的类型的,resultType用于简单的HashMap或者是简单的pojo对象,而resultSet是 ...