zoukankan      html  css  js  c++  java
  • shiro的启动过程-入口分析

    我们知道,在使用shiro的时候,需要在web.xml中配置一个DelegatingFilterProxy,这个过滤器就是shiro的入口。然后在applicationContext.xml注册ShiroFilterFactoryBean这个bean。需要注意的是过滤器中的filter-name要跟ShiroFilterFactoryBean的Id一样。原理就是,shiro使用了委托机制,DelegatingFilterProxy这个过滤器是spring的,它不具备shiro的功能,因此去spring容器中寻找id为shiroFilter的bean去替自己干活。(具体怎么委托的,后面再讲)

        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/system/login" />
            <property name="successUrl" value="/aa" />
            <property name="unauthorizedUrl" value="/system/unauthorized" />
            <property name="filterChainDefinitions">
                <value>
                    /js/** = anon
                    /css/** = anon
                    /images/** = anon
                    /sys/** = anon
                    /login/ = anon
                </value>
            </property>
        </bean>

    细心的人,可能就发现问题了。DelegatingFilterProxy是一个filter,它具备过滤器的功能,然而ShiroFilterFactoryBean只是一个普通的bean,它只实现了FactoryBean,BeanPostProcessor这两个接口,按道理来,它并不具备拦截器的功能。那它是怎么完成DelegatingFilterProxy的委托任务呢?

      原因就是:ShiroFilterFactoryBean实现了FactoryBean接口。FactoryBean是Spring容器提供的一种可以扩展容器对象实例化逻辑的接口。提供了这三个方法。

     第一个方法返回实例化的bean,第二个方法返回实例化bean的类型,第三个方法定义是否单例。

    接着看看ShiroFilterFactoryBean是怎么实现这3个方法的。

     看到返回一个SpringShiroFilter()的实例。

     返回SpringShiroFilter的类型。

    继续看,SpringShiroFilter其实是ShiroFilterFactoryBean的一个内部类,而SpringShiroFilter最终也实现了Filter,也就具有了过滤器的功能。

     至此,应该就明白了。DelegatingFilterProxy实际上就是委托ShiroFilterFactoryBean的内部类SpringShiroFilter来完成自己的功能。

    再思考问题:为什么shiro要这么设计。

    我们知道filter是tomcat创建的,它的创建要早于spring bean的创建。但是shiro真正执行功能的filter的创建又依赖spring创建的其他bean。这样就导致依赖的bean为null。因此就采用了这种委托机制。

    web.xml中targetFilterLifecycle这个属性的作用:

      如果不设置,默认是false。真正执行功能的是SpringShiroFilter这个类。因为这个类是又spring创建的,应该由spring来管理生命周期。但是它又是一个filter,默认是由tomcat来管理生命周期的。如果targetFilterLifecycle设置成true的话,filter在调用init()和destroy()方法时,就不起作用。

     

  • 相关阅读:
    Leetcode 16.25 LRU缓存 哈希表与双向链表的组合
    Leetcode437 路径总和 III 双递归与前缀和
    leetcode 0404 二叉树检查平衡性 DFS
    Leetcode 1219 黄金矿工 暴力回溯
    Leetcode1218 最长定差子序列 哈希表优化DP
    Leetcode 91 解码方法
    Leetcode 129 求根到叶子节点数字之和 DFS优化
    Leetcode 125 验证回文串 双指针
    Docker安装Mysql记录
    vmware虚拟机---Liunx配置静态IP
  • 原文地址:https://www.cnblogs.com/step-and-step/p/13330550.html
Copyright © 2011-2022 走看看