Shiro源码分析-初始化-SecurityManager

开涛的《跟我学Shiro》系列已即将完成,该系列囊括了shiro的绝大部分实用功能,并且在讲解如何用的过程中,也添加了其内部实现的原理。开涛主要以Shiro的使用者为角度,所以其原理部分是穿插在各个章节内的。

源码分析的第一篇以SecurityManager的初始化为题。
根据ini配置文件初始化shiro的代码主要为两段:

//解析ini文件为Ini对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-config.ini");
//根据Ini对象初始化SecurityManager对象
SecurityManager securityManager = factory.getInstance();

[color=red]
ini文件格式说明请参考:[/color]
[url]http://zh.wikipedia.org/wiki/INI%E6%AA%94%E6%A1%88[/url]
java解析ini的方式也比较多,有兴趣可以参考:
[url]http://my.oschina.net/tinyframework/blog/214309[/url]

[color=red][b]一、Shiro解析ini的步骤如下:[/b][/color]
[color=red]1、org.apache.shiro.config.IniSecurityManagerFactory类构造方法:[/color]

public IniSecurityManagerFactory(String iniResourcePath) {
this(Ini.fromResourcePath(iniResourcePath));
}

将ini文件解析交给Ini的静态方法fromResourcePath完成。并把解析后的Ini对象设置由自身持有

public IniSecurityManagerFactory(Ini config) {
setIni(config);
}


[color=red]2、org.apache.shiro.config.Ini类解析逻辑:[/color]

public static Ini fromResourcePath(String resourcePath) throws ConfigurationException {
if (!StringUtils.hasLength(resourcePath)) {
throw new IllegalArgumentException("Resource Path argument cannot be null or empty.");
}
//此处新建Ini对象
Ini ini = new Ini();
ini.loadFromPath(resourcePath);
return ini;
}

//根据资源路径获取输入流,交给load方法进行处理
public void loadFromPath(String resourcePath) throws ConfigurationException {
InputStream is;
try {
is = ResourceUtils.getInputStreamForPath(resourcePath);
} catch (IOException e) {
throw new ConfigurationException(e);
}
load(is);
}

ResourceUtils.getInputStreamForPath(resourcePath);这里支持三种获取资源的方式:
[table]
|classpath|shiro-config.ini|从类路径中查找ini配置|
|url|http://....../shiro-config.ini|从指定的url获取ini配置|
|file|D:\shiro-config.ini|从指定的文件路径获取ini配置|
[/table]


[color=red]3、对获取的资源输入流最终交给文本扫描器Scaner,执行过程代码片段:[/color]

public void load(Scanner scanner) {

String sectionName = DEFAULT_SECTION_NAME;
StringBuilder sectionContent = new StringBuilder();

while (scanner.hasNextLine()) {

String rawLine = scanner.nextLine();
String line = StringUtils.clean(rawLine);
//此处跳过ini文件格式的注释及空值
if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) {
//skip empty lines and comments:
continue;
}
//此处主要获取section部分,根据[]规则
String newSectionName = getSectionName(line);
if (newSectionName != null) {
//此处代码主要用于构造Section对象,并放进sections集合中
addSection(sectionName, sectionContent);

//reset the buffer for the new section:
sectionContent = new StringBuilder();

sectionName = newSectionName;

if (log.isDebugEnabled()) {
log.debug("Parsing " + SECTION_PREFIX + sectionName + SECTION_SUFFIX);
}
} else {
//normal line - add it to the existing content buffer:
sectionContent.append(rawLine).append("\n");
}
}

//finish any remaining buffered content:
addSection(sectionName, sectionContent);
}

上段代码主要是组装ini文件中的section。细心的同学会发现Section、Ini都是实现了Map接口。Section持有的LinkedHashMap容器实际上是当前section中的所有键值对,而Ini持有的LinkedHashMap容器实际上是所有section名称与section对象的键值对。
至此,ini文件的解析已经完成,其ini中的内容已全部以map的形式存放在Ini实例中。
至于保存的结果是什么样的呢?以下面的一段配置为例:

[main]
#authenticator
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator

Ini的sections属性[key=main,value=Section对象],此Section对象内部的props保存了所有main部分key-value映射。目前都是String类型,实例化在下一步完成的。

[color=red][b]二、由Ini实例构造SecurityManager对象[/b][/color]

SecurityManager securityManager = factory.getInstance();

IniSecurityManagerFactory的继承关系为:
IniSecurityManagerFactory->IniFactorySupport->AbstractFactory->Factory
这里的getInstance方法由最上级的抽象类:org.apache.shiro.util.AbstractFactory提供,源码如下:

//该方法只是用于判断是否单例(默认为单例)
public T getInstance() {
T instance;
if (isSingleton()) {
if (this.singletonInstance == null) {
this.singletonInstance = createInstance();
}
instance = this.singletonInstance;
} else {
instance = createInstance();
}
if (instance == null) {
String msg = "Factory 'createInstance' implementation returned a null object.";
throw new IllegalStateException(msg);
}
return instance;
}
//由子类IniFactorySupport创建实例
protected abstract T createInstance();

IniFactorySupport的createInstance实现如下(省略了无关紧要的日志、判断代码):

public T createInstance() {
//此处获取解析ini文件产生的Ini对象
Ini ini = resolveIni();
T instance;
if (CollectionUtils.isEmpty(ini)) {
//如果ini为空,则创建默认实例
instance = createDefaultInstance();
} else {
//根据ini对象创建实例
instance = createInstance(ini);
}
return instance;
}
protected abstract T createInstance(Ini ini);

protected abstract T createDefaultInstance();

上面两个抽象方法,则交给实现类IniSecurityManagerFactory完成了。
先阅读createDefaultInstance方法源码

protected SecurityManager createDefaultInstance() {
return new DefaultSecurityManager();
}

终于在这个不起眼的地方,看到了初始化最核心的接口SecurityManager了。稍微暂停一下,发个SecurityManager的类图:
[img]http://dl2.iteye.com/upload/attachment/0095/6391/5470ab90-8208-382f-9711-a6efadfbab46.png[/img]
由此图可以看出来,SecurityManager继承了三个接口(认证、授权、session管理),认证授权是安全框架最核心的功能,而shiro提供了自身的session管理机制(这也是shiro的一大亮点)。图中除了DefaultSecurityManager,其它所有类都是抽象类,由此可看出,DefaultSecurityManager是作为默认的安全管理器。
再来看new DefaultSecurityManager();做的事情

public DefaultSecurityManager() {
super();
this.subjectFactory = new DefaultSubjectFactory();
this.subjectDAO = new DefaultSubjectDAO();
}

这里暂时不深究每个构造器所做的具体事情。有兴趣的同学,可一直观察DefaultSecurityManager的所有父类构造器的处理逻辑。
[table]
|类名称|构造方法创建的默认对象|
|DefaultSecurityManager|DefaultSubjectFactory,DefaultSubjectDAO|
|SessionsSecurityManager|DefaultSessionManager|
|AuthorizingSecurityManager|ModularRealmAuthorizer|
|AuthenticatingSecurityManager|ModularRealmAuthenticator|
|RealmSecurityManager|无|
|CachingSecurityManager|无|
[/table]
在上面的表格中已经清晰的描述了各个类所设置的默认对象,至于用途后面再讲解。需要注意的是,RealmSecurityManager、CachingSecurityManager并没有设置默认的对象,所以这个是交给开发人员自己配置的。

接下来看createInstance实现细节:

protected SecurityManager createInstance(Ini ini) {
if (CollectionUtils.isEmpty(ini)) {
throw new NullPointerException("Ini argument cannot be null or empty.");
}
//SecurityManager的创建工作交给createSecurityManager方法
SecurityManager securityManager = createSecurityManager(ini);
if (securityManager == null) {
String msg = SecurityManager.class + " instance cannot be null.";
throw new ConfigurationException(msg);
}
return securityManager;
}

private SecurityManager createSecurityManager(Ini ini) {
//单独获取main部分进行初始化
Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME);
if (CollectionUtils.isEmpty(mainSection)) {
//try the default:
mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
}
return createSecurityManager(ini, mainSection);
}

private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
//创建DefaultSecurityManager,并且根据ini初始化realm
Map<String, ?> defaults = createDefaults(ini, mainSection);
//根据main部分构造对象(包括属性依赖,创建实例等)
Map<String, ?> objects = buildInstances(mainSection, defaults);
//从ReflectionBuilder的objects获取SecurityManager实例。ReflectionBuilder负责shiro的所有反射构造实例的工作,并且把实例放在objects的集合中持有。
SecurityManager securityManager = getSecurityManagerBean();
//如果显示指定了realm,则不会自动配置realm。
boolean autoApplyRealms = isAutoApplyRealms(securityManager);

if (autoApplyRealms) {
//如果在ini文件中未显示指定realm(即:securityManager.realms=$myRealm1)
//那么ini配置的所有realm会自动设置(即:realm1=test.Realm1)
//getRealms方法只是把ini配置的所有实例对象中实现Realm、RealmFactory接口的实例添加到SecurityManager中
Collection<Realm> realms = getRealms(objects);
//set them on the SecurityManager
if (!CollectionUtils.isEmpty(realms)) {
applyRealmsToSecurityManager(realms, securityManager);
}
}

return securityManager;
}

//创建默认的SecurityManager
protected Map<String, ?> createDefaults(Ini ini, Ini.Section mainSection) {
Map<String, Object> defaults = new LinkedHashMap<String, Object>();
//这里还是先创建了DefaultSecurityManager
SecurityManager securityManager = createDefaultInstance();
defaults.put(SECURITY_MANAGER_NAME, securityManager);
//判断ini是否配置了roles、users
if (shouldImplicitlyCreateRealm(ini)) {
//如果配置了roles或users,则创建IniRealm
Realm realm = createRealm(ini);
if (realm != null) {
defaults.put(INI_REALM_NAME, realm);
}
}

return defaults;
}
//对main部分配置的所有类型、属性进行实例化,并设置依赖,放到objects集合中
private Map<String, ?> buildInstances(Ini.Section section, Map<String, ?> defaults) {
this.builder = new ReflectionBuilder(defaults);
return this.builder.buildObjects(section);
}


再看看ReflectionBuilder如何对main进行实例化及依赖的设置:

public Map<String, ?> buildObjects(Map<String, String> kvPairs) {
if (kvPairs != null && !kvPairs.isEmpty()) {
//实例配置集合
Map<String, String> instanceMap = new LinkedHashMap<String, String>();
//属性依赖配置集合
Map<String, String> propertyMap = new LinkedHashMap<String, String>();

for (Map.Entry<String, String> entry : kvPairs.entrySet()) {
//如果ini配置的key包括.号,或者以.class后缀的名称,则认为类型配置
if (entry.getKey().indexOf('.') < 0 || entry.getKey().endsWith(".class")) {
instanceMap.put(entry.getKey(), entry.getValue());
//其它情况,则认为是属性依赖配置
} else {
propertyMap.put(entry.getKey(), entry.getValue());
}
}

// Create all instances
for (Map.Entry<String, String> entry : instanceMap.entrySet()) {
//实例化每个类型
createNewInstance((Map<String, Object>) objects, entry.getKey(), entry.getValue());
}

// Set all properties
for (Map.Entry<String, String> entry : propertyMap.entrySet()) {
//配置所有的依赖。必须有个先后顺序,先实例化再设置依赖
applyProperty(entry.getKey(), entry.getValue(), objects);
}
}

//SHIRO-413: init method must be called for constructed objects that are Initializable
//如果配置的类型实现了Initializable接口,则调用其init方法
LifecycleUtils.init(objects.values());

return objects;
}


SecurityManager的初始化部分已经完成。
FanucROBOGUIDE软件二次开发:使用ROBOGUIDEAPI进行编程 菜单栏:位于界面顶部,提供文件、编辑、视图、插入、格式、工具、窗口和帮助等选项。工具栏:包含常用的工具按钮,如新建、打开、保存、运行、停止、机器人控制等。工作站视图:显示工作站的3D模型,用户可以在这里放置机器人、工件、工具和其他设备。机器人控制面板:用于控制机器人运动,包括手动移动、程序编辑和运行。程序编辑器:在这里可以编写和编辑机器人程序,支持Fanuc的R-30iB Plus和R-30iB控制柜的程序格式。状态栏:显示当前工作站的状态信息,如机器人位置、程序状态等。 阅读详情

相关推荐

2023电赛B题实战解析:基于立创天空星开发板的同轴线缆长度与负载测量系统

本文详细解析了2023年全国大学生电子设计竞赛B题的实战方案,重点介绍了基于立创EDA天空星开发板(STM32F103)的同轴线缆长度与负载测量系统。文章深入剖析了两种核心测量方案,并推荐了更稳定易实现的NE555测电容法,提供了从硬件选型、电路设计到软件编程、参数标定的完整“施工图”,实测精度可达厘米级和皮法级,为电赛复现与高精度测量学习提供了清晰指导。

weixin_36303305的博客 230

关于java读取resource下文件,程序报错不存在问题的解决

先排除路径错误等低级错误。 一般读取某文件,比如在resource目录下的ehcache文件夹中有ehcache-shiro.xml文件,使用以下方式读取 ResourceUtils.getInputStreamForPath(“classpath:ehcache/ehcache-shiro.xml”); 代码中要思考,classpath意义。简明之意是,告诉程序到编译后的路径下去读取文件,这一点通过看源码可以理解。 如果出现了原本有文件,但仍报错不存在,可以从编译后的路径中,查看resource

weixin_43421537的博客 3448

3D医学影像分割新突破:手把手教你用MedSAM2快速标注CT/MRI数据(附3D Slicer插件配置)

本文详细介绍了如何利用MedSAM2模型进行3D医学影像分割,包括从环境准备到3D Slicer插件配置的全流程。通过实战案例和技巧分享,帮助医疗从业者快速掌握CT/MRI数据的高效标注方法,提升医学影像分析的准确性和效率。

ujm5678901的博客 298

shiro配置文件读取(二)

Shiro是一个简单、开源且强大的安全管理框架,是实现单点登录的理想选择,常被应用于java web应用中。 在java web中使用shiro时,可以使用一个INI文件对shiro进行配置,这仅需要在web.xml中配置一下IniShiroFilter的一个参数configPath [code="java"] ShiroFilter org.apa...

百威 400

GoPro官方API实战:从蓝牙配对到Wi-Fi流媒体,构建跨平台控制应用

本文详细解析了GoPro官方API的开发实践,涵盖蓝牙配对、Wi-Fi流媒体控制等关键技术。通过实战案例,指导开发者如何构建跨平台控制应用,解决设备发现、指令解析、视频流传输等核心问题,并分享Android平台迁移经验与常见问题排查方法。

weixin_30727835的博客 397

Shiro学习(3)shiroConfig配置类

配置原理:对SecurityManager来说他管理了所有的Realm,通过这些代码获取了Realm管理信息。注意SecurityManager导包,是shiro的SecurityManager。可以直接创建CustonRealm这个对象,也可以通过Realm创建。在web程序中,shiro进行权限控制是通过一组过滤器集合进行的操作。3、通用配置(跳转登录页面,为授权跳转的页面)4、开启对shiro注解的支持。3、配置shiro过滤器工厂。

m0_67403240的博客 2084

华为Atlas 300I推理卡驱动安装全攻略:从环境检查到常见问题解决

本文提供了华为Atlas 300I推理卡驱动安装的完整实战指南。从安装前的系统环境检查、内核版本匹配,到详细的二进制.run文件安装步骤、源码编译及高级定制化部署,涵盖了驱动安装的全流程。文章重点解析了安装过程中的关键决策、常见问题排查与解决方案,并针对生产环境的多卡配置、性能调优及安全加固给出了专业建议,旨在帮助用户高效、稳定地完成AI推理加速卡的部署。

swift5iosmith的博客 627

3.CacheManager(shiro缓存管理)

上一章我们讲了SecurityManager,接下来的章节顺序是根据SecurityManager的依次实现类的依赖组件来讲。 在讲cacheManager前,我们先了解下Cache。 Cache有效的存储临时对象来提升应用的性能。由于Cache不属于安全框架的核心功能,所以shiro本身并没有完全实现Cache机制。Cache接口相当于底层的缓存框架的顶层接口,shiro的一切的缓存操作都与这

浪子 1万+

淘宝链接跳转微信全攻略:自建合规中转页实现私域引流

在跨平台运营中,链接跳转是连接不同生态、实现流量引导的关键技术。其核心原理是通过服务器端或前端逻辑,将用户从一个平台的链接安全引导至目标页面,同时规避平台间的访问限制。这项技术的核心价值在于打破数据孤岛,实现跨平台用户沉淀与精细化运营,广泛应用于电商引流、私域流量构建和跨平台营销等场景。本文聚焦于**淘宝短链**与**企业微信**之间的跳转难题,提供了一套基于自建中转页面的完整工程解决方案,手把手教你如何通过合规的技术手段,将淘宝流量高效、安全地引导至微信生态,并实现数据追踪与客户分流。

weixin_34185512的博客 408

01-系统技术架构师必备——软件架构设计基础与核心概念

摘要 本文系统阐述了软件架构设计的核心概念与方法论,重点涵盖以下内容:1)软件架构的四大要素(构件、连接件、约束、配置)及其边界划分;2)Garlan & Shaw五大架构风格(数据流、调用/返回、独立构件、虚拟机、仓库)的典型应用场景;3)基于电商库存系统的架构选型实战案例,展示如何根据业务需求(高并发、最终一致性)选择事件驱动架构配合Saga模式;4)介绍ABSD、DSSA等主流架构方法论及ISO/IEEE标准体系。文章融合金融与互联网领域的架构实践经验,为技术架构师提供系统性的知识框架和决策参考。

模界 | AI工程化实践者 181

Spring源码:Resource 的 getInputStream

概述 Resource 是 Spring框架中统一管理底层资源的接口。 1、ClassPathResource // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.cor...

ruanhao1203的专栏 3433

手把手教你学simulink(26.8)--控制算法场景示例:基于强化学习的无人机姿态稳定控制系统

首先,我们需要定义无人机的姿态稳定控制环境。环境包括无人机的状态(姿态角、角速度等)和动作(电机转速)。我们还需要定义奖励函数,用于评估控制器的表现。matlab深色版本% 定义环境% 定义状态空间% 12个状态变量% 定义动作空间% 电机转速范围奖励函数用于评估控制器的表现。我们可以根据无人机的姿态误差、角速度误差以及控制输入的变化率来设计奖励函数。具体来说,当无人机的姿态接近设定值时,给予正奖励;当姿态误差较大或控制输入变化剧烈时,给予负奖励。matlab深色版本。

MHD0815的博客 494

Shiro源码分析(一)——初始化SecurityManager

一.Demo代码 Quickstart.java import org.apache.shiro.SecurityUtils; import org.apache.shiro.ini.IniSecurityManagerFactory; import org.apache.shiro.lang.util.Factory; import org.apache.shiro.mgt.SecurityManager; public class Quickstart { public static voi

MIKE2333的博客 927

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Shiro第一个程序官方快速入门程序Qucickstart详解教程

目录 一、下载解压 二、第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三、shiro.ini分析 四、Quickstart.java源码分析 1. 使用指定类初始化日志对象 2. 通过.ini文件创建SecurityManager实例 3. 获取当前执行的用户subject 4. 通过当前用户得到session存取值并打印 5. 测试当前用户是否被认证 6. 打印当前用户的主要身份信息 7. 判断当前用户角色 8. .

m0_54853503的博客 452

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Shiro学习(二)——读取配置文件与初始化SecurityManager的过程

概述 Shiro最先进行的操作就是读取配置文件和初始化SecurityManager。所以首先得搞清楚这个初始化的过程到底都做了什么,尤其是接口的SecurityManager实现类是什么,以及后面用到的默认realm又是什么。另外通过这个初始化过程,我们还能稍微窥探一下SecurityManager和Realm的架构。 读取配置文件 在Shiro使用的例子中,最开始一般都会调用以下语句: Factory<org.apache.shiro.mgt.SecurityManager>.

sadoshi的专栏 1468

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【SpringBoot】Shiro(二)第一个程序认证和自定义Realm

Shiro环境搭建和第一个DEMO

Ryoujou的博客 380

Shiro 源码分析(7) - 安全管理器(SecurityManager)

摘要:Apache Shiro框架的核心组件SecurityManager充当安全管理的"大脑",协调身份认证、授权决策、会话管理等核心功能。它采用多重接口隔离设计,遵循单一职责原则,通过DefaultSecurityManager等实现类提供默认功能,支持Web环境扩展和安全策略配置。该组件具备完善的认证授权流程、会话管理机制和RememberMe服务,同时提供缓存集成、事件监听、并发控制等高级特性,支持自定义扩展和外部化配置。SecurityManager的设计体现了开闭原则、依赖倒

油墨香^-^的博客 119

Shiro源码学习之一

1.lock与unlock if (account.isLocked()) { throw new LockedAccountException("Account [" + account + "] is locked."); } 参考:Java中锁的应用之-Lock

编程的本质是数学问题 1863

Shiro原理及源码分析

安全管理器的创建是依赖于认证、授权,缓存、数据源等诸多组件的,你可以各自创建功能组件对象然后交给SecurityManger,配置的方式,选择很多,比如你可以通过SpringXML配置,也可以用YAML文件或者Properties文件配置等,领域对象,在Shiro和你的应用程序安全数据(比如登录的用户名、密码,用户的权限等)之间架起一座沟通的桥梁,安全管理器要验证用户身份,或者要获取用户对应的权限,是分别通过认证组件(),授权找授权组件(),会话找会话组件(.........................

lipengyao2010的专栏 2251

Apache Shiro 全面源码解析汇总

什么是shiro? Apache Shiro官网上对Shiro的解释如下: Apache Shiro (pronounced “shee-roh”, the Japanese word for ‘castle’) is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management and can ..

wangxi06的专栏 524

shiro安全框架源码分析--启动加载过程

Apache Shiro是一个简单易用且强大而灵活的开源Java安全框架,以下简称Shiro。它干净利落地处理身份认证、授权以及企业会话管理和加密。项目最近使用shiro安全框架,自己就读了相关的源码,菜鸟一枚,本博客主要用于自我学习记录使用,有什么不对的请多多指教。 一。shiro架构 最主要有三个概念: subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行...

weixin_41920291的博客 788

源码分析shiro认证授权流程

源码分析shiro认证授权流程1. shiro介绍 Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户“登录”; 授权 - 访问控制; 密码加密 - 保护或隐藏数据防止被偷窥; 会话管理 - 每用户相关的时间敏感的状态。 2. shiro源码分析 Subject:即“当前操作用户”。但是,在Shiro中,Sub

个人视角下的技术领域探索 892

shiro源码分析(一)入门

[size=medium]最近闲来无事,准备读个框架源码,经别人推荐shiro,那就准备读读其中的设计。开涛大神已经有了跟我学Shiro系列,那我就跟着这个系列入门然后再深入源代码,所以我的侧重点就是源码分析。 话不多说,上开涛大神的入门案例 地址[url]http://jinnianshilongnian.iteye.com/blog/2019547[/url]:[/size] [cod...

乒乓狂魔的专栏 499

Shiro源码分析之ShiroFilterFactoryBean

创建核心Filter 同其他框架一样,都有个切入点,这个核心Filter就是拦截所有请求的。 通过web.xml中配置的Filer进入,执行init方法获取这个instance,调用下面的createInstance方法创建核心Filter: protected AbstractShiroFi...

chengtaopai5214的博客 474
上一篇: 基于Snaker的三种流程案例(选择分支,任务并行,会签)
下一篇: Shiro源码分析-初始化-Realm
Dead_Knight
博客等级 码龄19年 6粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值