Apache Shiro学习(2)--源码分析

来源:互联网 发布:js原型链是啥 编辑:程序博客网 时间:2024/06/03 14:03

简介

以一个纯粹用servlet编写的web应用为例来看看shiro是怎样配置的,从这些配置中先找到shiro工作的起点。以下实例来源于Apache Shiro源码包:

这里写图片描述

从上面可以看出普通的应用需要配置两部分,即:

  1. 监听器org.apache.shiro.web.env.EnvironmentLoaderListener
  2. 过滤器 org.apache.shiro.web.servlet.ShiroFilter

过滤器真正作用的是每个请求,而监听器用于监听web应用的声明周期事件,所以接下来的分析从监听器开始

EnvironmentLoaderListener

先来看看该监听器的继承结构

这里写图片描述

其中EventListener接口是一个标记接口,所有的事件监听器接口都要实现这个接口;

而ServletContextListener接口是ServletConetext的监听器,从其内部结构可以看出它用于控制容器的启动的关闭。以下是其内部方法;

这里写图片描述

现在来看看EnvironmentLoaderListener内部的实现:

这里写图片描述

这个类中并没有实质性的操作,其内部的操作是由其父类EnvironmentLoader完成的。我们整体分析一下这个类。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

通过上面的分析可以看出这个类有两个作用:

  1. 当容器启动时,读取 web.xml 文件,从中获取 WebEnvironment 接口的实现类(默认是 IniWebEnvironment),初始化该实例,并将其加载到 ServletContext 中。
  2. 当容器关闭时,销毁 WebEnvironment 实例,并从 ServletContext 将其移除。

这个类启动时会得到 WebEnvironment 接口的实现类,而默认情况下其实现类是IniWebEnvironment 这个类,不妨来看看这个类的结构

这里写图片描述

下面具体分析一下这个类的代码

这里写图片描述

这里写图片描述

Init函数中做了两件事,即寻找配置文件和解析配置文件,其中解析配置文件部分在configure方法中进行,实现如下:

这里写图片描述

主要是创建了 WebSecurityManager 对象和 FilterChainResolver 对象,这两个对象将会在后面的shiroFilter 中起到作用。

ShiroFilter

先来看看其继承结构

这里写图片描述

下面从这些结构分析其作用:

 Filter接口

这里写图片描述

这个接口是servlet规范中的接口,所有的过滤器都要实现这个接口

 ServletContextSupport类

这里写图片描述

这个类主要是提供对ServletContect对象的封装

 AbstractFilter类

这里写图片描述

这个类是FilterConfig的封装类,在类中提供了一个空的方法 onFilterConfigSet,在初始化时调用,但其实现是由子类完成的,从类的继承结构中可以看出其子类是NameableFilter,我们先来看看该类实现的一个接口(Nameable接口),再来具体的分析该类。

 Nameable接口

这里写图片描述

这个接口的作用是为它的实现类提供可命名功能。

 NameableFilter类

这里写图片描述

这个类的特性就是可以获取或设置名称。

 OncePerRequestFilter类

从这个名称就可以大概猜出这个filter的作用,即每一个请求只会执行一次。何谓执行一次呢。我们来看看下面这个例子:

这里写图片描述

在这个配置中等号左边是url,右边是这个url将会经过的过滤器。OncePerRequestFilter这个类的作用就是保证当我们对同一个url配置同样的过滤器时,该过滤器只会执行一次。下面来看看这个类的具体实现:

这里写图片描述

这里写图片描述

这里写图片描述

通过上面的doFilter方法就可以知道一个请求上同一个过滤器只会执行一次的原因了。配置文件中还有一项配置也可以在这里找到原因:

这里写图片描述

这里通过ssl.enable = false 禁用了ssl过滤器,这样设置的好处是我们可以统一控制是否使用某一个过滤器。具体的原因在doFilter方法中,即在执行之前会判断该过滤器的enable字段,如果禁用了(即enable = false)则会忽略当前过滤器直接执行下一过滤器,否则会调用doFilterInternal()方法进行过滤操作,这个方法是抽象方法,具体的实现是在其子类AbstractShiroFilter中实现的。

 AbstractShiroFilter类

首先来看看这个类中几个重要的变量

这里写图片描述

其中前两个变量用来保存在监听器中生成的WebSecuritymanager和FilterChainResolver对象。

接下来看看这个类中重要的几个方法:

1..onFilterConfigSet()方法

这里写图片描述

这里写图片描述

2.. doFilterInternal方法

这里写图片描述

其中executeChain()方法是执行过滤器链,具体实现如下:

这里写图片描述

 ShiroFilter类

先来看看这个类是怎样实现的

这里写图片描述

这个类相对较简单,只是进行简单的初始化工作,主要的部分都在其父类中实现了。

至此,filter的几个层次就分析完了。

原创粉丝点击