单例模式是指一个类保证只有一个实例,下面简单介绍一下单例模式的实现方式:
实现单例模式注意两点:
构造函数必须声明为private
变量必须声明为private static
懒汉 线程不安全
public class Singleton { private static Singleton singleton; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
接下来为了保证能够在多线程下正常工作:
线程安全的实现方式:
public class Singleton { private static Singleton singleton; private Singleton() { } public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
这种情况具备很好的lazy loading,但是效率低
代理模式, 顾明思议就是让别人给你做事, 比如说我们要租房子,平时又没有时间, 所以只好找房产中介来为我们找房子,我们只需要告诉中介要找什么的房子 大概什么价位就可以了, 那么房产中介就是所谓的代理:
说说代理之前我们来看一个例子吧:
定义一个接口
public interface IHello { void sayHello(String name); }
定义实现类:
public class IHelloImpl implements IHello { @Override public void sayHello(String name) { System.out.println("Hello " + name); } }
那么如果我想在System.out.println("Hello: " + name)之前加before() 和之后加 after() 用于测试方法的性能监控, 很多人可能会说直接这样好了:
public class IHelloImpl implements IHello { @Override public void sayHello(String name) { before(); System.out.println("Hello " + name); after(); } public void before(){ System.out.println("Before"); } public void after(){ System.out.println("After"); } }
这种做法在大型项目中会有一个问题, 会造成项目中代码冗余, 扩展性不高, 那么能不能让一个专门的类去执行Before() 和After() 方法呢 当然是可以的 这就是代理模式的由来:
接下来我们定义一个代理类:
public class IHelloProxy implements IHello { private IHello hello; public IHelloProxy() { this.hello = new IHelloImpl(); } @Override public void sayHello(String name) { before(); hello.sayHello(name); after(); } public void before() { System.out.println("Before"); } public void after() { System.out.println("After"); } public static void main(String[] args) { IHello hello = new IHelloProxy(); hello.sayHello("test"); } }
运行后的结果为:
Before Hello test After
那么这样是解决之前的问题了, 但是如果IHello 接口变了, 我们还需要在IHelloProxy里面去修改代码,代码的解耦性不好
所以就出现了动态代理啦
接下来我们来看下动态代理我们应该如何实现: 动态代理需要实现InvocationHandler接口:
public class DynamicProxy implements InvocationHandler { private Object obj; private DynamicProxy(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result = method.invoke(obj, args); after(); return result; } public void before() { System.out.println("Before"); } public void after() { System.out.println("After"); } public static void main(String[] args) { IHello hello = new IHelloImpl(); DynamicProxy dynamicProxy = new DynamicProxy(hello); IHello helloProxy = dynamicProxy.getProxy(); helloProxy.sayHello("tester"); } @SuppressWarnings("unchecked") public <T> T getProxy() { return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } }
public class CglibProxy implements MethodInterceptor { private Object obj; public Object getInstance(Object obj) { this.obj = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.obj.getClass()); enhancer.setCallback(this);//回调方法 return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object result = method.invoke(obj, objects); after(); return result; } public void before() { System.out.println("Before"); } public void after() { System.out.println("After"); } public static void main(String[] args) { IHello hello = new IHelloImpl(); CglibProxy proxy = new CglibProxy(); IHello hello1 = (IHello)proxy.getInstance(hello); hello1.sayHello("tester"); } }
运行结果为:
Before Hello tester After