spring對類的實例化,定義了接口InstantiationStrategy,同時先做了個簡單實現類SimpleInstantiationStrategy。采用實現部分,抽象部分的策略。為了更好的擴展性,把一部分再次抽象,后面可以采用多種實現方式。
下面具體代碼分析:
public class SimpleInstantiationStrategy implements InstantiationStrategy { // FactoryMethod的ThreadLocal對象,線程所有的變量 private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<Method>(); // 返回當前線程所有的FactoryMethod變量值 public static Method getCurrentlyInvokedFactoryMethod() { return currentlyInvokedFactoryMethod.get(); } // 第一種實例化方法,實現部分,部分抽象 @Override public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { // bd對象定義里,是否包含MethodOverride列表;spring有兩個標簽參數會產生MethodOverrides ,分別是 lookup-method,replaced-method // 沒有MethodOverride對象,可以直接實例化 if (bd.getMethodOverrides().isEmpty()) { // 實例化對象的構造方法 Constructor<?> constructorToUse; // 鎖定對象,使獲得實例化構造方法線程安全 synchronized (bd.constructorArgumentLock) { // 查看bd對象里是否含有 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; // 沒有就生成 if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() { @Override public Constructor<?> run() throws Exception { return clazz.getDeclaredConstructor((Class[]) null); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[]) null); } // 生成成功后,賦值給bd對象,后面使用 bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } // 反射生成對象 return BeanUtils.instantiateClass(constructorToUse); } else { // 有MethodOverride對象,需要使用另一種實現方式,之類實現 return instantiateWithMethodInjection(bd, beanName, owner); } } // 第一種實例化方法的抽象部分 protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) { throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy"); } // 第二種實例化方法,實現部分,抽象部分 @Override public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args) { // 查看bd對象是否有MethodOverride對象 // 沒有MethodOverride,則直接實例化對象 if (bd.getMethodOverrides().isEmpty()) { if (System.getSecurityManager() != null) { // use own privileged to change accessibility (when security is on) AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { ReflectionUtils.makeAccessible(ctor); return null; } }); } // 反射實例化對象 return BeanUtils.instantiateClass(ctor, args); } else { // 有MethodOverride,之類實現實例化方法 return instantiateWithMethodInjection(bd, beanName, owner, ctor, args); } } // 第二種實例化方法的抽象部分 protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner, Constructor<?> ctor, Object... args) { throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy"); } // 第三種實例化方法,全部實現 @Override public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Object factoryBean, final Method factoryMethod, Object... args) { try { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { ReflectionUtils.makeAccessible(factoryMethod); return null; } }); } else { ReflectionUtils.makeAccessible(factoryMethod); } // currentlyInvokedFactoryMethod,這塊暫時還沒看到在哪個地方用到了 // 先取出原有的 Method Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get(); try { // 設置當前的Method currentlyInvokedFactoryMethod.set(factoryMethod); // 使用factoryMethod實例化對象 return factoryMethod.invoke(factoryBean, args); } finally { // 實例化完成,恢復現場 if (priorInvokedFactoryMethod != null) { currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod); } else { currentlyInvokedFactoryMethod.remove(); } } } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(factoryMethod.getReturnType(), "Illegal arguments to factory method '" + factoryMethod.getName() + "'; " + "args: " + StringUtils.arrayToCommaDelimitedString(args), ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(factoryMethod.getReturnType(), "Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex); } catch (InvocationTargetException ex) { String msg = "Factory method '" + factoryMethod.getName() + "' threw exception"; if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory && ((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) { msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " + "declaring the factory method as static for independence from its containing instance. " + msg; } throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException()); } } }
注:lookup-method, replaced-method的使用,可以看之前的文章。