shiro realm 注解失败问题解决过程
做为一名在.net混了八九年的老兵油子,转战java时间并不长,刚开始做项目完全是凭借对C#的认识来做,虽然遇到一些问题,但实际结果显示C#在语言上和java还是有很大相似度,而且微软的MVC与Spring MVC也是那么的神似,这也是为什么我在做项目前并未对java进行系统的学习也能做项目的原因。最近稍微有些空闲时间,所以决定从基础开始系统的学习java,这里并没有太多高深技术可分享的,本篇给大家分享我解决问题的一个经验:触类旁通或者叫举一反三,对了还有一点,对于存在可优化点的部分要不轻言放弃。
困扰以久的问题:
项目中应用shiro进行登录权限认证,在Realm实现类中注解服务不成功,得到的实例是null。网上遇到同类问题的还不少,可能每个人的项目情况不同,我并未从中得到正确的解决方案。
@Autowired
private ISecurityService securityService;
有两种方法可以解决:
- 通过ApplicationContext动态获取实例
private ISecurityService securityService; private void initSecurityService() {
if (null == this.securityService) {
ApplicationContext appCtx = ApplicationContextUtils.getApplicationContext();
this.securityService = appCtx.getBean(ISecurityService.class); }
}
- 通过静态属性注解,这个方法可以用来调试spring是否有对这个属性进行过注解。为什么下面代码中的变量是静态的呢?当不是静态类型时,调试过程中的确有进行过注解,而且是注解成功的,但当程序执行后,shiro获取到的实例为null,并不是之前注解过的实例,将这个变量修改为静态的之后运行成功。
private static ISecurityService securityService;
@Autowired
public void setSecurityService(ISecurityService securityService) {
securityService = securityService;
}
以上两种写法都比较恶心,但当时对于spring类扫描的不了解,也只能做罢。在知识不够的情况下,如果一味的去钻也许不一定会有完美的结果,所以我选择暂时放弃。
项目中遇到过使用数据库事务不生效的情况,当时同事的解释是spring扫描的问题,在加载事务配置时,不能扫描Controller。后来有时间研究了下,由于我们使用了spring mvc,而且在web.xml中采用了非常经典的Application Context +DispatcherServlet Context结构。而有意思的是我们并没有给Application Context配置有关资源扫描以及Bean加载的信息,只有一个shiro配置文件的加载,结果就是项目所有的bean加载都集中在DispatherServlet这个MVC的配置文件中。
也有说如果只存在一个Servlet,那么可以选择只使用一个Context,这样也可以避免误使用双亲上下文所带来的问题,这个做法我还没有尝试,有时间研究下。
Application Context是什么?
它是应用程度级别的一个上下文,这个上下文其中一个重要功能就是负责提供对访问数据库事务,数据层以及其它一些你想通过应用程序访问的需求(这里也许描述的不够准确,有兴趣的可上官方网站上去看文档)。比如上面的方法一,获取bean就是通过这个上下文对象动态获取得到。
DispatcherServlet Context是什么?
一个应用程序可以定义多个Servlet,每个Servlet都有一个属于自己的上下文,我们项目中只有一个Servlet。
Application Context与DispatcherServlet Context的关系?
DispatcherServlet Context的父级是Application Context,会继承所有Application Context所定义的内容。这里推荐两个贴子,说的挺清楚的。
- http://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring-frame
- http://stackoverflow.com/questions/18578143/about-multiple-containers-in-spring-framework/18580299#18580299
为什么在加载数据库事务配置前,不能扫描Controller?这个我目前并不知道明细的原因,只大概知道是Spring设计规则问题,DispatherServlet中如果在数据库事务配置加载前扫描了包含Controller在类的命名空间,结果就是事务并不具备事务能力。所以我们在DispatherServlet配置文件中会出现两段扫描代码:
- 先只扫描Controller
<context:component-scan base-package="cn.wanmei.party" use-default-filters="false">
<context:include-filter expression="org.springframework.web.bind.annotation.Controller" type="annotation"/>
</context:component-scan>
- 。。。。。扫描加载其它配置
- 加载数据库配置,由于事务的存在,这里在扫描时需要去掉对于Service的扫描,避免二次重复扫描产生不可预期的结果。
<context:component-scan base-package="cn.wanmei.party">
<context:exclude-filter expression="org.springframework.web.bind.annotation.RestController" type="annotation"/>
</context:component-scan>
<import resource="mybatis.xml"/>
上面这种将几乎所有配置全部写在DispatherServlet配置文件中的做法有缺点:
- 架空了原本为Application Context配置的root-context配置文件(只有一个shiro配置文件,不包含任何bean加载相关的内容)
- 将原本属于Application Context做的事情转交给DispatherServlet,会造成扫描问题
- 配置会显得复杂,我个人的意见是DispatherServlet尽量只配置与Servlet自身相关的,而像数据库配置最好放在root-context这个Application级别的配置中
以上大部分都是在描述事务不生效的问题,那与我文前提到的Realm实现类中通过Autowired注解服务失败有什么关联呢?之前提到了Application Context主要功能之一就是提供应用程序对于事务,数据层以及其它类实例的访问,那么在Realm实现类中提供类的注解实例当然是在职责范围内,为此我们需要对配置文件做变更:
- root-context,增加包扫描,将数据库配置转移到进来
<context:component-scan base-package="cn.wanmei.party">
</context:component-scan>
<import resource="mybatis.xml"/>
<import resource="redis-context.xml"/>
<import resource="spring-shiro-web.xml" />
- DispatherServlet:只加载与Servlet相关的配置,在扫描类配置上需要删除对Service的扫描,避免二次扫描问题。
<context:component-scan base-package="cn.wanmei.party">
<context:exclude-filter expression="org.springframework.stereotype.Service" type="annotation"/>
</context:component-scan>
解决后:
1:root-context饱满了
2:Application Conext 有活干了,事务呀什么的应有的它都有了
3:DispatherServlet的配置清爽了
经过测试,事务正常,Realm中的注解正常,从此再也不需要使用文前提到的那两种恶心的方式了。本文通过项目中事务不生效的问题,联想到Realm实现类注解失败与之存在关联,最后通过实践进一步证实推测,也进一步了解了Spring的上下文知识。
shiro realm 注解失败问题解决过程的更多相关文章
- 记录sqoop同步失败问题解决过程,过程真的是很崎岖。(1月6日解决)
记录sqoop同步失败问题解决过程,过程真的是很崎岖.事发原因:最近突然出现sqoop export to mysql时频繁出错.看了下日志是卡在某条数据过不去了,看异常.看sqoop生成的mr并未发 ...
- 解决自定义Shiro.Realm扩展类不能用注解(@Resource或@Autowire)自动装配的问题
问题产生原因:加载Realm时其他Spring配置文件(xml)尚未加载,导致注入失败. 解决方法:编写一个设置类把注入工作提前完成. package com.xkt.shiro import org ...
- 【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面
这几天粗浅的把shiro整合到spring中,并且注解控制shiro用户/角色/权限And/OR 步骤: 1.首先maven搭建web项目 2.创建数据库 user/role/authority 其中 ...
- 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...
- shiro授权+注解式开发
shiro授权和注解式开发 1.shiro授权角色.权限 2.Shiro的注解式开发 ShiroUserMapper.xml <select id="getRolesByUserId& ...
- Sonatype Nexus 服务启动失败问题解决
Sonatype Nexus 服务启动失败问题解决 问题前述: 近日在开发机本机安装了 Oracle 数据库快捷版 11g2 之后,重启电脑后发现本机的maven代理服务无法访问. 现象 通过 Win ...
- Shiro 权限注解
Shiro 权限注解: Shiro 提供了相应的注解用于权限控制,如果使用这些注解就需要使用AOP 的功能来进行 判断,如Spring AOP:Shiro 提供了Spring AOP 集成用于 ...
- Shiro Realm
Realm: 在实际应用中,shiro从数据库中获取安全数据(如用户.角色.权限),而不是从ini中,可作为安全数据源 即SecurityManager要验证用户身份,那么它需要从Realm获取相应的 ...
- [INS-30131] 执行安装程序验证所需的初始设置失败问题解决,windows下oracle安装步骤
[INS-30131] 执行安装程序验证所需的初始设置失败问题解决,windows下oracle安装步骤 配置: 系统:windows10 数据库:Oracle Database 12c 第 1 版 ...
随机推荐
- C#、.Net代码精简优化(空操作符(??)、as、string.IsNullOrEmpty() 、 string.IsNullOrWhiteSpace()、string.Equals()、System.IO.Path 的用法)
一.空操作符(??)在程序中经常会遇到对字符串或是对象判断null的操作,如果为null则给空值或是一个指定的值.通常我们会这样来处理: .string name = value; if (name ...
- WPF入门教程系列十四——依赖属性(四)
六.依赖属性回调.验证及强制值 我们通过下面的这幅图,简单介绍一下WPF属性系统对依赖属性操作的基本步骤: 借用一个常见的图例,介绍一下WPF属性系统对依赖属性操作的基本步骤: 第一步,确定Base ...
- app的同源和域的问题
app的同源和域的问题
- EFProf Entity Framework Profile 工具
SQL Server Profiler用来跟踪应用程序发送到SQL Server中的SQL语句,用于检测性能,查找问题.Entity Framework 也有它的跟踪工具EFProf,用于跟踪Enti ...
- 如何对SharePoint网站进行预热(warmup)以提高响应速度
问题描述 SharePoint Server是一个易于使用的协作平台,目前在越来越多的企业中被应用开来.SharePoint Server是通过网站的形式向最终用户提供服务的,而这个网站是基于ASP. ...
- 50款免费 PSD 名片设计模板源文件下载《下篇》
名片是陌生人之间建立联系的最便捷.最有效的工具.名片它可能是给你的客户留下正面的印象第一步,另一方面,名片是一个企业最重要和最符合成本效益的营销工具之一,尤其是对于刚刚起步的企业.这里收集了50款免费 ...
- Halcon与opencv格式的转换
IplImage* ImageProcess::HImageToIplImage(Hobject &Hobj) { IplImage* pImage; HTuple htChannels; c ...
- SQL Server安全(7/11):使用跨数据库所有权链接(Cross-Database Ownership Chaining)的跨数据库安全
在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...
- Javascript编程风格
Douglas Crockford是Javascript权威,Json格式就是他的发明. 去年11月他有一个演讲(Youtube),谈到了好的Javascript编程风格是什么.我非常推荐这个演讲,它 ...
- C# 6.0的字典(Dictionary)的语法
在C# 6.0,当我们使用Dictionary时,我们可以使用新语法,来去简化程序以提高效率. public Dictionary<string, object> OldToolLocat ...