在springMVC中要使用shiro,一般都遵循下面的配置:

applicationContext-shiro.xml

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" />
.....</bean>

web.xml

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener><!-- Spring MVC Servlet -->
<servlet><servlet-name>springServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath*:/spring/springmvc-common.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>springServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><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>

看到这样的配置,难免有些疑问:
1. 这三者是怎样融合到一起的
2. 为什么那个bean的id和filter的name保持一样
3. 为什么配置的bean是一个factoryBean而不是普通的bean

带着这样的疑问,跟踪下启动过程。正向跟踪,即在refresh方法中开展,锁定getBean方法,通过name来追踪shiroFilter,发现关系比较乱,而且费时。于是锁定ShiroFilterFactoryBean的getObject方法,反向追踪,获得了下面的序列图:

重点就是:

配置的监听器启动容器的初始化,完成上面ShiroFilterFactoryBean的创建和维护

servlet触发过滤器Filter的init方法,在initDelegate方法中会getBean(),这个getBean最终会转移到ShiroFilterFactoryBean的getObject方法

上面的问题第二个看源码很容易解决。

在调用DelegatingFilterProxy初始化方法时:

@Override
protected void initFilterBean() throws ServletException {synchronized (this.delegateMonitor) {if (this.delegate == null) {// If no target bean name specified, use filter name.if (this.targetBeanName == null) {this.targetBeanName = getFilterName();}// Fetch Spring root application context and initialize the delegate early,// if possible. If the root application context will be started after this// filter proxy, we'll have to resort to lazy initialization.WebApplicationContext wac = findWebApplicationContext();if (wac != null) {this.delegate = initDelegate(wac);}}}
}protected final String getFilterName() {return (this.filterConfig != null ? this.filterConfig.getFilterName() : this.beanName);
}protected Filter initDelegate(WebApplicationContext wac) throws ServletException {Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);if (isTargetFilterLifecycle()) {delegate.init(getFilterConfig());}return delegate;
}

获取的这个名字将用来追寻之前spring维护的那个bean,并且还要通过它来拿到一个Filter实例。

那么为什么配置的那个bean是一个factoryBean而不是一个普通的bean?

首先shiro是基于过滤器来实现的,配置一个filter是必要的。

但是和spring在一起使用,就要让spirng来管理一些filter依赖的bean,例如安全管理器,还有自己实现的认证和鉴权服务之类。如果shiro直接写一个过滤器,那spring的容器早就启动完了,你这些东西怎么注入。

所以只有提前初始化那些过滤器需要的东西,让他们依附于某个特定类,通过约定来在过滤器的初始化中获取(这个就是前面提到的相同的name)。

那么这个bean可以是普通的bean吗?答案是不可以,毕竟shiro要的这个bean得是一个filter。普通的bean只能获取到它本身的实例,要获取filter那么它必须实现Filter接口。但是创建filter的方法你掌控不了了,spring会通过反射来创建对象,怎么创建是它说了算,自定义的创建是不可能了。

这时候你就只能使用FactoyBean了。

这个FactoryBean当然得交给shiro实现。不过filter的创建方式自由了,我们可以通过getBean来获取这个filter,另一边的filter配置还有必要吗?

当然必要。因为这个filter怎么创建不重要,切入web的生命周期才重要,这个配置是一个规范。所以spring引入了这么一个类: DelegatingFilterProxy。就是一个代理类,自定义的实现转移到factoryBean了,这里就是公共类,主要操作是在容器中追踪并获取之前的factoryBean,并在初始化方法中获取需要的filter。

Spring容器的启动依靠监听器,而filter是在监听器之后,依靠servlet规范,在listener,filter和servlet三者之间寻找契机,并形成一个共荣圈,Spring把这种关系处理得非常妙!

转载于:https://www.cnblogs.com/lucare/p/8679131.html

Shiro切入Spring的方式相关推荐

  1. Spring Boot2 整合 Shiro ,两种方式全总结!

    前言:在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 文章目录 一.Spring Securit ...

  2. Apache Shiro和Spring Security的详细对比

    参考资料: 1)Apache Shiro Apache Shiro:http://shiro.apache.org/ 在Web项目中应用 Apache Shiro:http://www.ibm.com ...

  3. 面向切面(AOP)之Spring接口方式 schema配置方式 aspectj注解方式

    一.初识AOP   关于AOP的学习可以参看帮助文档:spring-3.2.0.M2\docs\reference\html目录下index.html的相关章节      1.AOP:Aspect-O ...

  4. 项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示...

    1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 ...

  5. Shiro的鉴权方式

    一. 怎么用 Shiro 支持三种方式的授权 编程式:通过写 if/else 授权代码块完成: Subject subject = SecurityUtils.getSubject(); if(sub ...

  6. Spring学习4-面向切面(AOP)之Spring接口方式

    一.初识AOP    关于AOP的学习可以参看帮助文档:spring-3.2.0.M2\docs\reference\html目录下index.html的相关章节       1.AOP:Aspect ...

  7. apache shiro怎么升级_Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 一般来说,Spring Security 和 S ...

  8. 【开发技术】2万字分析shiro、spring security两大安全框架,spring session,OAuth2 入门级教程

    SpringBoot 内容管理 Shiro 创建demo 用户[用户包括token ,角色,权限] :fist_oncoming: Shiro配置 配置5个基本对象 + 3额外对象 路径匹配有先后 : ...

  9. 搭建Spring Boot2.X集成Hibernate5项目,并集成传统SSH老项目的安全认证组件,以Spring Boot方式开发项目并集成到老系统

    搭建Spring Boot2.X集成Hibernate5项目,并集成传统SSH老项目的安全认证组件,以Spring Boot方式开发项目并集成到老系统 场景 可行性分析 搭建Spring Boot集成 ...

最新文章

  1. [20160513]Restrict Session与静态监听.txt
  2. 理解Linux系统中的load average(图文版)转载
  3. 无法上外网又需要同步Gradle
  4. [CTSC2010]星际旅行
  5. maven 加入第三方库_关于maven,你还要翻阅多少资料才能整理出这一份完整文档...
  6. android 双人黑白棋开发博客,黑白棋 - 软件资讯 - 课堂党年级博客
  7. 数据结构-栈5-栈的应用-后缀转中缀
  8. c语言斐波那契数列递归数组,C语言数据结构学习:递归之斐波那契数列
  9. [转载]INNO Setup 使用笔记
  10. php手机i选择图片多选,ios 相册图片多选 带预览功能
  11. 【安装sql 2008步骤】
  12. halcon 深度学习标注_Halcon教程之-HALCON 18.05正式发布,深度学习不再需要GPU
  13. 3dmax测试软件自动关闭,3dmax软件会自动关闭解决方案
  14. Android裁剪图片总结
  15. csSEnet注意力网络
  16. 计算机网络的未来的发展前景,浅谈计算机网络的未来发展趋势
  17. ghost还原固态硬盘_高级格式化_固态硬盘到底能不能使用Ghost软件?终于说明白了...
  18. 网易2016实习研发笔试
  19. 因子模型:套利定价理论APT
  20. 猫眼APP影院静态界面

热门文章

  1. Leetcode题库 19.删除链表的倒数第N个结点(双指针法 C实现)
  2. GCC __builtin_expect与kernel指令序列优化
  3. 怎样取消无线配置服务器,如何 去掉无线配置服务器
  4. mysql性能测试工具msyqlslap_MySQL性能测试工具 mysqlslap
  5. zookeeper 命令
  6. 写一个判断素数的函数,在主函数输入一个整数,输出是否是素数的消息。
  7. JavaScript高级程序设计之基本概念篇
  8. 2015 10月21日 工作计划与执行
  9. 开发DBA(APPLICATION DBA)的重要性
  10. DDD:关于聚合的思考