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 ...
随机推荐
- bzoj4881 线段游戏——上升序列方案数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4881 连题意都转化不了了... 题意是要求从一个数列中选出两个上升序列的方案数: 先判断是否 ...
- 【WebRTC音频预处理单元APM的整体编译及使用 - android】
前言 在写[单独编译使用WebRTC的音频处理模块 - android]一文之前,就一直想直接把WebRTC的音频处理引擎VoE整个儿编译出来供自己的项目使用,但限于技术拙劣.时间紧迫,所以没能成功. ...
- bzoj 2792: [Poi2012]Well【二分+贪心】
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const ...
- [Swift]编程语言:文档修订历史
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 作为一个程序员,你了解 win 上有哪些必装的软件吗
关于 win 的一些基础必知内容之前已经分享过,没有看过的可以戳此处→Windows 使用之那些你还不知道操作 新系统安装的第一个软件 Google Chrome 毫无疑问,作为程序员应该是首选的浏览 ...
- Kafaka入门篇
1.Apache Kafka - 简介 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端点传递到另一个端点. Kafka适合离线 ...
- Spring + MyBaits 日志初始化两遍的问题
偶然发现一个问题,记录一下以备查询. 问题:系统启动时发现日志初始化了两次 14:28:04.798 [main] DEBUG org.apache.ibatis.logging.LogFactory ...
- 洛谷 P2742 [USACO5.1]圈奶牛Fencing the Cows || 凸包模板
整篇都是仅做记录... 蓝书上的板子.水平序,单调栈.先求下凸包,再求上凸包.叉积的作用是判定向量的位置关系. 48行的作用是在求上凸包的时候不至于去删下凸包中的点.上凸包中第一个点被认为是t1. 另 ...
- 洛谷 P2634 [国家集训队]聪聪可可
点分板子2333 注释都是错过的地方 #include<cstdio> #include<algorithm> using namespace std; typedef lon ...
- Tree CodeForces -932D
错误记录:如下注释语句 #include<cstdio> #include<algorithm> using namespace std; typedef long long ...