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的使用,可以看之前的文章。 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM