有线程安全和不安全的写法
public class SingletonL { private static SingletonL instance=null; private SingletonL(){} public static SingletonL getInstance(){ if(instance == null){ instance=new SingletonL(); } return instance; } } 复制代码
没有线程安全问题,但是浪费内存空间
class SingletonE{ private static SingletonE instance=new SingletonE(); private SingletonE(){ } public static SingletonE getInstance(){ return instance; } } 复制代码
整个懒汉和饿汉,synchronized内外都加了if判断,保证线程安全
class DoubleCheck{ private static DoubleCheck instance=null; private DoubleCheck(){} public static DoubleCheck getInstance(){ if(instance==null){ synchronized (DoubleCheck.class){ if (instance==null){ instance=new DoubleCheck(); } } } return instance; } } 复制代码
只适用于静态域的情况
class Singleton{ private static class SingletonHolader{ private static final Singleton INSTANCE=new Singleton(); } private Singleton(){} public static final Singleton getInstance(){ return SingletonHolader.INSTANCE; } } 复制代码
enum SingletonEnum{ INSTANCE; } 复制代码
根据传入一个唯一的标识来获得Bean对象。
由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化职责交给工厂对象。
动态的给对象增加职责,即增加其额外功能。Wrapper和Decorator
为其他对象提供一种代理以控制这个对象的访问,SpringAOP,JDK动态代理和CGLib代理
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。ApplicationListener
定义一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
Spring中在实例化对象的时候用到Strategy模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
Spring中的JdbTemplate的execute方法
面向切面编程
通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能。
根据类加载器和接口创建代理类,面向接口生成代理
利用反射机制生成一个实现代理接口的匿名类,在调用方法前调用InvokeHandler来处理
利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理,不需要实现接口
Spring中目标对象实现接口默认采用JDK动态代理,也可以强制使用CGLib;
目标对象没有实现接口,必须采用CGLib库,spring会自动在JDK和CGLib之间转换