私有构造函数的类如何new实例
一、背景
在应用程序的启动过程中,我们经常会遇到某个初始化实例如果构造失败,可能导致整个应用启动失败。如果发生在上线过程中,灰度的机器起不来,可能造成剩余机器负载陡增,甚至整个服务垮掉。因此对某些非关键依赖的初始化实例,我们希望它不会阻塞整个应用启动的进程,有两种方案:一是容器框架支持、二是Mock技术。
二、实现
采用mock技术,我们返回一个初始化的空壳子,其所有的方法都返回空值,需要确保空值的逻辑不会影响业务流程,任何涉及业务逻辑的点不能mock。
代码实现
import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.objenesis.ObjenesisHelper; @Bean public MyBean buildBean() { try { //
return MyBean.valueOf(); } catch (Exception e) { e.printStackTrace(); } return mock(); } private MyBean mock() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyBean.class); enhancer.setUseCache(false); enhancer.setCallbackType(methodInterceptorWithNullReturn.getClass()); final Class<?> proxyClass = enhancer.createClass(); Enhancer.registerCallbacks(proxyClass, new Callback[] {methodInterceptorWithNullReturn}); return (MyBean) ObjenesisHelper.newInstance(proxyClass); } private MethodInterceptor methodInterceptorWithNullReturn = (obj, method, args, proxy) -> null;
三、参考连接
https://brixomatic.wordpress.com/2012/12/22/dynamic-proxies-for-classes/