spring实例化二:SimpleInstantiationStrategy
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的使用,可以看之前的文章。
松下问童子,言师采药去。
只言此山中,云深不知处。