zoukankan      html  css  js  c++  java
  • 当存在多个ioc容器的项目中使用security框架的问题

    当项目中存在2个以上IOC容器时,初始化security框架时会抛出异常

    spring ioc父容器  扫描service...

    springMVC ioc子容器 扫描controller...

    这个异常主要在于哪一个ioc来扫描WebAppSecurityConfig类,

    分析问题:

    如果spring 扫描 :则Filter在spring ioc容器中

    如果springMVC扫描:则Filter在springMVC 容器中

    通常情况下使用security都是对请求做权限控制,所以不能由spring ioc容器来进行扫描,进而衍生出下面的异常

    分析问题所在:

    首先明确三组件加载顺序:

    首先contextLoaderListener初始化 创建Spring IOC容器

    其次DelegatingFilterProxy初始化 查找ioc容器 创建bean
    最后DispatcherServlet初始化 创建springMVC  IOC容器
     
    通过debug调试可以确定,在DelegatingFilterProxy初始化时,会查找有没有ioc容器,如果有则继续查找有没有bean,没有bean则抛出上面的异常信息
    当没有IOC容器时,则会放弃查找,在第一次请求发出时在次查找ioc容器,也就是dispatcherServlet初始化后再次进行查找,如果找不到ioc容器会抛异常,如果找到会继续查找是否有这个bean
    遗憾的是,这次依然找不到,通过Debug调试源码发现,第二次查找时查的依然是spring ioc容器
    这个常量表示了永远会找父容器;
    两种解决方案
    方案一:不使用contextLoaderListener,将两个IOC容器合二为一由DispatcherServlet加载所有spring配置文件
    这样会造成DelegatingFilterProxy在初始化时,找不到ioc容器,则放弃,在第一次请求时spring的配置文件全部加载,这是在查找则有了,
    问题点:会破坏现有程序结构,原本是 ContextLoaderListener 和 DispatcherServlet两个组件创建两个 IOC 容器,现在改成只有一个。
     
    方案二:修改源码
    方法:1.在初始化时直接跳过查找ioc容器的环节
       2.第一次请求时直接找springMVC容器  
    在项目路径下创建同包同类名的DelegatingFilterProxy类
    将249行注释掉
    WebApplicationContext wac = findWebApplicationContext(); //查找ioc容器
    添加自己写的代码
    // 获取servletContext对象
    ServletContext sc = this.getServletContext();
    // 拼接SpringMVC将IOC容器存入servletContext域的时候使用的属性名
    String servletName = "dispatcherServlet";
    String attrName = FrameworkServlet.SERVLET_CONTEXT_PREFIX+servletName;
    WebApplicationContext wac = (WebApplicationContext)sc.getAttribute(attrName);
    servletName 具体是什么值参照自己项目中web.xml中配置的dispatcherServlet的servlet-name名;

    这时security环境初步搭建完成!
     
  • 相关阅读:
    LeetCode 128. 最长连续序列
    MySQL的information_schema
    maven项目板块的pom.xml配置
    mybatis打印SQL日志
    MySQL的时间字段转换
    mysql的csv数据导入与导出
    一致性协议
    分布式事务
    事务基本信息
    分布式系统定义及特点
  • 原文地址:https://www.cnblogs.com/myPrBB/p/12594515.html
Copyright © 2011-2022 走看看