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环境初步搭建完成!
     
  • 相关阅读:
    分布式计算原理
    消息的有序性
    CAP再解释
    数据建模
    领导层级的跨越
    如何上云|什么是多机房多活架构
    mysql导出导入数据
    Qt 串口 封装好的类 直接使用
    C++ 在类的定义时初始化非静态变量
    Qt error C3646: 未知重写说明符
  • 原文地址:https://www.cnblogs.com/myPrBB/p/12594515.html
Copyright © 2011-2022 走看看