• 覆写 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 配置的更多相关文章

  1. Spring Boot . 4 -- 定制 Spring Boot 配置 【2】

    除了第一篇中使用 覆写的方式进行 自动配置的更改外,还可以通过 Spring Boot 中提供的 application.properties 文件改变应用的运行时配置.这种配置的方式粒度是非常精细的 ...

  2. Spring Boot实践——基础和常用配置

    借鉴:https://blog.csdn.net/j903829182/article/details/74906948 一.Spring Boot 启动注解说明 @SpringBootApplica ...

  3. 自定义的Spring Boot starter如何设置自动配置注解

    本文首发于个人网站: 在Spring Boot实战之定制自己的starter一文最后提到,触发Spring Boot的配置过程有两种方法: spring.factories:由Spring Boot触 ...

  4. Spring Boot源码探索——自动配置的内部实现

    前面写了两篇文章 <Spring Boot自动配置的魔法是怎么实现的>和 <Spring Boot起步依赖:定制starter>,分别分析了Spring Boot的自动配置和起 ...

  5. Spring Boot使用Druid和监控配置

    Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource 整体步骤: (1)    --   Druid简单介绍,具体看官网: (2)     ...

  6. Spring Boot应用的后台运行配置

    酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: 运行Spring Boot的应用主类 使用Mave ...

  7. Spring boot 的 properties 属性值配置 application.properties 与 自定义properties

    配置属性值application.properties 文件直接配置: com.ieen.super.name="MDD" 自定义properties文件配置:src/main/r ...

  8. Spring Boot 启动(二) 配置详解

    Spring Boot 启动(二) 配置详解 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Boot 配置 ...

  9. Spring Boot 中使用 @Transactional 注解配置事务管理

    事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...

随机推荐

  1. cmath函数整理

    double a= pow(double x, double y)://返回x的y次方. double a= sqrt(double x)://返回x的平方根. double a=ceil(doubl ...

  2. 在使用react时的异步问题解决

    在时用react时, 常常会出现在创建一个对象后, 对象还没有创建完成就被使用的异步问题, 介于这种问题, 一种解决方法就是使用Promise, 将需要被等待的那一步放到Promise中, Promi ...

  3. ES6躬行记(23)——Promise的静态方法和应用

    一.静态方法 Promise有四个静态方法,分别是resolve().reject().all()和race(),本节将着重分析这几个方法的功能和特点. 1)Promise.resolve() 此方法 ...

  4. .NET Core 跨平台物联网开发:SDK 属性、方法、委托、类(四)

    系列教程目录 (一) 连接阿里云IOT (二) 设置委托事件 (三) 上报属性 (四)  SDK文档 属性.方法.委托.类 http://pan.whuanle.cn/index.php?dir=up ...

  5. codeforces 570 D. Tree Requests (dfs)

    题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...

  6. Frequency of String CodeForces - 963D

    http://codeforces.com/contest/963/problem/D 题解:https://www.cnblogs.com/Blue233333/p/8881614.html 记M为 ...

  7. AsyncTask官方教程-推荐用AsyncTask少用Thread

    Using AsyncTask AsyncTask allows you to perform asynchronous work on your user interface. It perform ...

  8. c#如何使用replace函数将"\"替换成"\\"

    当我使用 String str="c:\aa.xls"; str=str.Replace("\","\\");时,括号为红色错误的,那么如何 ...

  9. TestNG基本注解(一)

    TestNG基本注解   注解 描述 @BeforeSuite 注解的方法将只运行一次,运行所有测试前此套件中. @AfterSuite 注解的方法将只运行一次此套件中的所有测试都运行之后. @Bef ...

  10. Mybatis查询select操作

    先看select标签的属性: 说几点: resultType和resultMap都是用来表示结果集的类型的,resultType用于简单的HashMap或者是简单的pojo对象,而resultSet是 ...