java设计模式在公众号的应用——我是一个快乐的单例
终于可以休息了,寻一把躺椅,安置于庭院,携一壶好茶,品一番风轻云淡。。。
自由自在的呼吸,伸手即可触摸阳光的温度,此时此刻,我就是我,像一个单例。
终于可以休息了,寻一把躺椅,安置于庭院,携一壶好茶,品一番风轻云淡。。。
自由自在的呼吸,伸手即可触摸阳光的温度,此时此刻,我就是我,像一个单例。
想起『设计模式』,就像想起了很久很久以前的故事,今日重新拾起,不妨用java结合微信公众号来尝尝这经典的二十三式。
我是一个快乐的单例
说起单例的经典应用,一定要提 spring的依赖注入,可谓是行业经典。
在spring4的版本中,单例是这么出来的:
1 /** 2 * Return the (raw) singleton object registered under the given name. 3 * <p>Checks already instantiated singletons and also allows for an early 4 * reference to a currently created singleton (resolving a circular reference). 5 * @param beanName the name of the bean to look for 6 * @param allowEarlyReference whether early references should be created or not 7 * @return the registered singleton object, or {@code null} if none found 8 */ 9 protected Object getSingleton(String beanName, boolean allowEarlyReference) { 10 Object singletonObject = this.singletonObjects.get(beanName); 11 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { 12 synchronized (this.singletonObjects) { 13 singletonObject = this.earlySingletonObjects.get(beanName); 14 if (singletonObject == null && allowEarlyReference) { 15 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); 16 if (singletonFactory != null) { 17 singletonObject = singletonFactory.getObject(); 18 this.earlySingletonObjects.put(beanName, singletonObject); 19 this.singletonFactories.remove(beanName); 20 } 21 } 22 } 23 } 24 return (singletonObject != NULL_OBJECT ? singletonObject : null); 25 }
既用到缓存,又有线程锁进行防护,可谓双管齐下。
Java单例模式可能是最简单也是最常用的设计模式,一个完美的单例需要做到哪些事呢?
单例六要素
- 单例
- 延迟加载
- 线程安全
- 没有性能问题
- 防止序列化产生新对象
- 防止反射攻击
而青鸟的脑子就比较简单,想不了这么复杂的事情,平时是这么用的:
1 package org.yi.parttern; 2 3 /** 4 * @ClassName: SingletonMe 5 * @author 青鸟 6 * @date 2018年2月16日 下午2:11:16 7 * @describe 8 * 我是一个快乐的单例 9 * 微信公众号:青鸟的记忆 10 * 博客:www.cnblogs.com/stobird/p/8450140.html 11 * 12 */ 13 public class SingletonMe { 14 /** 15 * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,而且只有被调用到时才会装载(装在过程是由jvm保证线程安全) 16 * ,从而实现了延迟加载 17 */ 18 private static class SingletonHolder { 19 /** 20 * 静态初始化器,由JVM来保证线程安全 21 */ 22 private static SingletonMe instance = new SingletonMe(); 23 } 24 25 /** 26 * 私有化构造方法 27 */ 28 private SingletonMe() { 29 } 30 31 /** 32 * 这个模式的优势在于:getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本 33 */ 34 public static SingletonMe getInstance() { 35 return SingletonHolder.instance; 36 } 37 38 }
使用内部类来维护单例的实例,当SingletonMe 被加载时,其内部类并不会被初始化,故可以确保当 SingletonMe 类被载入JVM时,不会初始化单例类。
只有 getInstance() 方法调用时,才会初始化 instance。
同时,由于实例的建立是时在类加载时完成,故天生对多线程友好,getInstance() 方法也无需使用同步关键字。
下一篇预告:站在工厂的角度看单例,喜欢的朋友也可以关注体验一下哦。。。
公众号回复 单例 ,试一下吧。