需求:
实现年结功能
实现
-
SpringBoot整合Shiro实现动态过滤链
参看Shiro实现动态权限管理 -
Shiro动态过滤链加载前载入动态数据源
上一节说到自定义Runner 实现ApplicationRunner接口达成系统启动完成后初始化动态数据源
由于Shiro动态过滤链实在系统启动过程中加载的,所以我们在这里必须要保证动态数据源在Shiro之前加载
- 自定义Configuration类,
import cn.apcinfo.sys.pojo.AnnualInfo;
import cn.apcinfo.sys.service.AnnualService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class InitDynamicDataSourceListener {
private static final Logger log = LoggerFactory.getLogger(InitDynamicDataSourceListener.class);
@Autowired
private AnnualService annualService;
// 由于Spring中不允许存在相同名称的Bean,此处指定Bean的名称,防止因Bean名称冲突导致系统报错
@Bean(name = "initDynamicDataSourceSonListener")
public InitDynamicDataSourceListener initDynamicDataSourceListener() {
// 获取待注册数据源Bean的年度信息
List<AnnualInfo> annualInfoList = annualService.list();
// 注意: 可以在此处先注册已存在的数据源,由于系统内需要在年结操作完成后动态添加数据源,所以注册数据源的工作未放在此处处理
// // 注册各年度数据源
// for(AnnualInfo annualInfo:annualInfoList){
// ManualRegisteredDsBeanUtil.register((ConfigurableApplicationContext) applicationContext,annualInfo,properties);
// }
//
// // 验证Bean是否已注册成功
// Map<String, DruidDataSource> beans = applicationContext.getBeansOfType(DruidDataSource.class);
// if(beans.size() != annualInfoList.size()+1){
// // 抛出系统运行错误,中止应用启动
// throw new Error("Application Start Failed: DataSource Bean Register Failed,Please Check DataSource Configuration is valid!");
// }
return new InitDynamicDataSourceListener();
}
}
- 通过依赖注入保证配置类的执行顺序,这里主要保证动态数据源的注册在Shiro之前
/**
* Shiro 权限认证配置类
*/
@Configuration
public class ShiroConfiguration {
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager,
AuthenticateService authenticateService,
AnnualService annualService,
// 只是为了保证Bean初始化的顺序
@Qualifier("initDynamicDataSourceSonListener") InitDynamicDataSourceListener initDynamicDataSourceListener) {
ShiroPermissionFilterFactoryBean shiroFilterFactoryBean = new ShiroPermissionFilterFactoryBean();
// 此处代码省略...
return shiroFilterFactoryBean;
}
}
- 修改动态注册Bean工具类,只保留修改的部分,其余部分代码参看上一篇
/**
* Druid DataSource Bean 注册工具类
*/
public class ManualRegisteredDsBeanUtil {
/**
* 主动向Spring容器中注册bean
* @param applicationContext Spring容器
* @param annualInfo DataSource 年度信息
* @return 返回容器中DataSourceBean的名称及Bean的实例集合
*/
public static Map<String,DruidDataSource> register(
ConfigurableApplicationContext applicationContext,
AnnualInfo annualInfo,
DbConnProperties dbConnProperties) {
// 省略部分代码...
Map<S