内容简介:从shiro源码角度学习建造者设计模式
今天就和大家分享一下shiro源码里面使用到的建造者模式。在介绍建造者模式相关知识之前,我们先来看一段例子分析。
从一个简单的例子说起
我们在使用shiro获取登录用户的时候,比如使用ini文件配置用户角色权限,我们可以这样写:
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:demo01_getstarted.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject currentUser = SecurityUtils.getSubject();
SecurityUtils.getSubject()
是获取当前用户,我们跳进去看一下,是怎么获取的
public static Subject getSubject() { Subject subject = ThreadContext.getSubject(); if (subject == null) { subject = (new Subject.Builder()).buildSubject(); ThreadContext.bind(subject); } return subject; }
上面代码,首先从ThreadContext里面获取Subject,获取不到就创建,我们看看创建过程,跳进去看看 (new Subject.Builder()).buildSubject()
干了什么。 这里不贴过长代码了,Builder是Subject的静态内部类,用来完成Subject的复杂创建过程,使得调用就无需关注Subject怎么创建的,只要知道怎么获取Subject就可以了。 我们看一下,Builder类里面干了什么事情
public static class Builder { private final SubjectContext subjectContext; private final SecurityManager securityManager; public Builder() { this(SecurityUtils.getSecurityManager()); } public Builder(SecurityManager securityManager) { if (securityManager == null) { throw new NullPointerException("SecurityManager method argument cannot be null."); } this.securityManager = securityManager; this.subjectContext = newSubjectContextInstance(); if (this.subjectContext == null) { throw new IllegalStateException("Subject instance returned from 'newSubjectContextInstance' " + "cannot be null."); } this.subjectContext.setSecurityManager(securityManager); } protected SubjectContext newSubjectContextInstance() { return new DefaultSubjectContext(); } protected SubjectContext getSubjectContext() { return this.subjectContext; } public Builder sessionId(Serializable sessionId) { if (sessionId != null) { this.subjectContext.setSessionId(sessionId); } return this; } public Builder host(String host) { if (StringUtils.hasText(host)) { this.subjectContext.setHost(host); } return this; } public Builder session(Session session) { if (session != null) { this.subjectContext.setSession(session); } return this; } public Builder principals(PrincipalCollection principals) { if (principals != null && !principals.isEmpty()) { this.subjectContext.setPrincipals(principals); } return this; } public Builder sessionCreationEnabled(boolean enabled) { this.subjectContext.setSessionCreationEnabled(enabled); return this; } public Builder authenticated(boolean authenticated) { this.subjectContext.setAuthenticated(authenticated); return this; } public Builder contextAttribute(String attributeKey, Object attributeValue) { if (attributeKey == null) { String msg = "Subject context map key cannot be null."; throw new IllegalArgumentException(msg); } if (attributeValue == null) { this.subjectContext.remove(attributeKey); } else { this.subjectContext.put(attributeKey, attributeValue); } return this; } // 创建Subject public Subject buildSubject() { return this.securityManager.createSubject(this.subjectContext); } }
我们可以看到,Builder完成了Subject一些列的复杂创建过程,包括sesson、sessionid等的设置等过程。最后会调用 buildSubject()
方法来创建Subject。 我们就不继续深入看 this.securityManager.createSubject(this.subjectContext)
里面干了什么事了。 回到前面,我们可以看到Subject对象会包含许多的当前用户信息,但是这些信息框架底层都替我们设置好了,我们只要获取Subject对象即可,调用 Subject currentUser = SecurityUtils.getSubject();
就可以了。 这样看来,是不是特别方便。这些都归功于建造这模式的使用。
建造这模式基本概念
通过分析shiro源码,我们对建造这模式有了一个初步的感知,目前大家可以理解成创建复杂对象由一个建造类来完成。那么,我们就来学习一下建造者模式的一些理论知识,相信大家结合上面的例子分析,不会感到吃力乏味的。
什么是建造者模式
建造者模式又称为生成器模式。
建造者模式:它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。 参考维基百度百科:生成器模式
可能有些读者看了这句话迷迷糊糊的,那么这句话是什么意思呢?结合上面的例子,我们可以知道Subject对象有很多属性,通过SubjectContext对象来保存的,最后创建Subject对象的时候,传递SubjectContext就可以了。这样比如,我们创建两个有不同属性值的Subject:
Subject user_1 = new Subject.Builder().authenticated(false).buildSubject(); Subject user_2 = new Subject.Builder().authenticated(true).buildSubject();
我们创建Subject的不同实现方法,比如authenticated()一个设置true,一个设置false,我们就构造出来了有不同表现(属性)的Subject对象了,一个是授权,一个是未授权。
为什么使用建造者模式
使用建造者模式可以屏蔽复杂的对象创建过程,对象的创建对调用者来说是透明的,这样就使得程序耦合度降低,程序可读性和维护性提高了。
结束语
对于设计模式,大家不要机械地学习,个人觉得主要理解其设计思想和好处就可以了。在编码过程中大家不要刻意去使用它,而是去思考如何运用它更好地设计代码。这样,经过时间的推磨,大家就可以真正做到把 设计模式 融会贯通,手到拈来。
以上所述就是小编给大家介绍的《从shiro源码角度学习建造者设计模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。