美文网首页Spring相关时序图系列
Spring AOP(5)通过Aspect的BeanDefini

Spring AOP(5)通过Aspect的BeanDefini

作者: 涣涣虚心0215 | 来源:发表于2021-01-18 01:00 被阅读0次

    Spring AOP(4)再解<aop:advisor>与<aop:aspect>是AOP生成代理Proxy对象的核心,里面涉及到基于XML解析注册DefaultBeanFactoryPointcutAdvisorAspectJPointcutAdvisor这两个核心bean的BeanDefinition,而这两个bean都包含了关于Advice通知以及PointCut切点Bean,那么他们之间是怎么注入的?这需要结合之前IOC相关的知识一起来理解。

    1. Spring依赖注入的方式:

    • Set方法注入(byName、byType)
    • 构造器注入
    • 静态工厂的方法注入
    • 实例工厂的方法注入
      实现方式:
    • 基于XML
    • 基于注解:@Autowired,@Value,@Resource。。。
    1.1)Set方法注入
    public class UserDao {
        public void login() {
            System.out.println("login...");
        }
    }
    
    public class UserService {
        private UserDao userDao;
        //提供set方法
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        public void login() {
            userDao.login();
        }
    }
    

    基于XML通过set方法的时候,可以根据name或者type去查找相对应的bean(注意这里没有通过<property>去指定reference)。

    基于XML
    1.2)构造器注入
    public class UserDao {
        public void login() {
            System.out.println("login...");
        }
    }
    public class UserService {
        private UserDao userDao;
        //提供构造方法
       public UserService(UserDao userDao) {
            this.userDao = userDao;
        }
        public void login() {
            userDao.login();
        }
    }
    XML配置文件
    <bean id="userDao" class="com.gary.spring.UserDao" >
    </bean>
    <bean id="userService" class="com.gary.spring.UserService" autowire="constructor">
     </bean>
    
    1.3)静态工厂的方法注入

    可以通过静态工厂的方法来获取自己需要的对象,而不是直接托管给Spring创建bean。

    public class UserDao {
        public void login() {
            System.out.println("login...");
        }
    }
    
    public class UserService {
        private UserDao userDao;
        //提供set方法
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        public void login() {
            userDao.login();
        }
    }
    //提供UserDao的工厂类
    public class UserDaoFactory {
        public static UserDao initUserDao() {
            UserDao userDao = new UserDao();
            System.out.println("factory new dao: "+userDao);
            return userDao;
        }
    }
    

    xml配置:userDao的类指向Factory类,并指定factory-method。

    静态工厂

    2. 源码解析

    再次回顾Spring IOC的核心流程就是
    getBean() -->
    doGetBean() -->
    getSingleton()- -> 检查单例缓存,这里涉及三级缓存和bean依赖循环的处理。
    getObjectForBeanInstanc() --> 这一步会检查是不是需要经过FactoryBean的getObject()去获取真正的bean。
    getDependsOn() --> 对dependent bean的处理
    getSingleton(String beanName, ObjectFactory<?> singletonFactory) --> 核心代码,调用createBean()。
    createBean()-->
    resolveBeforeInstantiation() --> 调用BeanPostProcessor的beforeInstantiation,提前初始化Advisor
    doCreateBean()-->
    createBeanInstance() --> 创建bean的实例
    addSingletonFactory() --> 添加二级缓存,也给AOP创建动态代理的机会
    populateBean() --> 给bean的property属性设值
    initializeBean() --> 初始化bean,核心代码。

    上面简述了Spring注入的几种方式,那么就上述几个测试代码,我们再一次进行Spring的源码分析。

    2.1)针对于set注入
    在这里我们对1.1)的配置文件做一些修改:

    <bean id="userDao" class="com.gary.spring.UserDao" />
    </bean>
    <bean id="userService" class="com.gary.spring.UserService" autowire="byName" />
    
    修改一下增加property reference
    <bean id="userDao" class="com.gary.spring.UserDao" />
    <bean id="userService" class="com.gary.spring.UserService" autowire="byName">
        <property name="userDao" ref="userDao"/>
    </bean>
    

    修改的区别就是加上了Property的reference:

    • 如果不加,PropertyValues属性在加载BeanDefinition的时候就是null,因为autowire是"byName",所以在创建userService的时候,populateBean()会通过PropertyDescriptor去检查自己的属性UserDao,并且如果有符合条件的属性且不在PropertyValues属性里,就通过getBean()加载需要注入的类,然后加入PropertyValues属性中;
    • 如果加了Property的reference,那么PropertyValues属性在加载BeanDefinition的时候就有了UserDao,那么就不需要通过autowireByName去加载了。
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        。。。
        //PropertyValues:包含以一个或多个PropertyValue对象的容器
        //如果mdb有PropertyValues就获取其PropertyValues
    
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        //如果配置了AutowireMode是byName或者byType
    
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            //new一个新的pvs, MutablePropertyValues是PropertyValues接口的默认实现。
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            //添加新的property,根据name
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                //通过bw的PropertyDescriptor属性名,查找出对应的Bean对象,将其添加到newPvs中
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            /添加新的property,根据类型type
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                //通过bw的PropertyDescriptor属性类型,查找出对应的Bean对象,将其添加到newPvs中
                autowireByType(beanName, mbd, bw, newPvs);
            }
            //newPvs此时已经包含了pvs的属性值
            //     以及通过AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE自动装配所得到的属性值
            pvs = newPvs;
        }
    
        //工厂是否拥有InstiationAwareBeanPostProcessor
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            //遍历工厂内的所有后置处理器
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //postProcessProperties:在工厂将给定的属性值应用到给定Bean之前,对它们进行后处理,不需要任何属性扫描符
                    //让ibp对pvs增加对bw的Bean对象的propertyValue,或编辑pvs的proertyValue
                    //-- CommonAnnotationBeanPostProcessor:处理@Resource,查找到resource直接通过InjectedElement.inject()通过 field.set(bean, value)
                    //-- AutowiredAnnotationBeanPostProcessor:处理@Autowired和@Value,就是查找Autowire注解等修饰的property,并且通过InjectedElement.inject()通过 field.set(bean, value);反射设置注入值
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            //从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        //如果需要依赖检查
        if (needsDepCheck) {
            if (filteredPds == null) {
                //从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            //检查依赖项:主要检查pd的setter方法需要赋值时,pvs中有没有满足其pd的需求的属性值可供其赋值
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    
        if (pvs != null) {
            //应用给定的属性值,解决任何在这个bean工厂运行时其他bean的引用
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }
    //根据名字查找需要注入的property
    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        //获取bw中有setter方法 && 非简单类型属性 && mbd的PropertyValues中没有该pd的属性名的 PropertyDescriptor 属性名数组
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            //如果BeanFactory中存在该Property对应的Bean,或者外部注册的singleton实例
            if (containsBean(propertyName)) {
                //通过BeanFactory获取该bean实例
                Object bean = getBean(propertyName);
                //将propertyName,bean添加到pvs中
                pvs.add(propertyName, bean);
                //注册propertyName与beanName的依赖关系
                registerDependentBean(propertyName, beanName);
                
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                            "' by name: no matching bean found");
                }
            }
        }
    }
    //获取bw中有setter方法 && 非简单类型属性 && mbd的PropertyValues中没有该pd的属性名的 PropertyDescriptor 属性名数组
    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        Set<String> result = new TreeSet<>();
        //获取BeanDefinition的所有属性值
        PropertyValues pvs = mbd.getPropertyValues();
        //获取BeanWrapper的所有属性描述对象
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            //如果 pd有写入属性方法 && 该pd不是被排除在依赖项检查之外 && pvs没有该pd的属性名 && pd的属性类型不是"简单值类型"
            if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                //将pdd的属性名添加到result中
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }
    
    

    从上面代码看,在applyPropertyValues()之前都是来获取有效的pvs(PropertyValues),比如通过autowireByName或者通过BeanPostProcessor(@Autowired,@Value,@Resource)等等。拿到有效的pvs之后,就会进行applyPropertyValues()。

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        ...
        //创建BeanDefinitionValueResolver:它将beanDefinition对象中包含的值解析为应用于目标bean实例的实际值
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    
        // Create a deep copy, resolving any references for values.
        // 创建一个深拷贝,解析任何值引用
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            //如果pv已经是转换后的值
            if (pv.isConverted()) {
                //将pv添加到deepCopy中
                deepCopy.add(pv);
            }
            //pv需要转换值
            else {
                String propertyName = pv.getName();
                //获取pv的原始属性值
                Object originalValue = pv.getValue();
                //交由valueResolver根据pv解析出originalValue所封装的对象
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                //可转换标记: propertyName是否bw中的可写属性 && prepertyName不是表示索引属性或嵌套属性
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    //将resolvedValue转换为指定的目标属性对象,
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        //设置到pv中
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
                else if (convertible && originalValue instanceof TypedStringValue &&
                        !((TypedStringValue) originalValue).isDynamic() &&
                        !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                    pv.setConvertedValue(convertedValue);
                    deepCopy.add(pv);
                }
                else {
                    //标记还需要解析
                    resolveNecessary = true;
                    //根据pv,convertedValue构建PropertyValue对象,并添加到deepCopy中
                    deepCopy.add(new PropertyValue(pv, convertedValue));
                }
            }
        }
        if (mpvs != null && !resolveNecessary) {
            mpvs.setConverted();
        }
    
        // Set our (possibly massaged) deep copy.
        try {
            //按原样使用deepCopy构造一个新的MutablePropertyValues对象然后设置到bw中以对bw的属性值更新
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }
    //将beanDefinition对象中包含的值解析为应用于目标bean实例的实际值,
    public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
        // We must check each value to see whether it requires a runtime reference
        // to another bean to be resolved.
        //如果是RuntimeBean,调用beanFactory.getBean(refName)
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            return resolveReference(argName, ref);
        }
        。。
        //如果是BeanDefinition相关的,就通过resolveInnerBean(): beanFactory.createBean(actualInnerBeanName, mbd, null)
        else if (value instanceof BeanDefinitionHolder) {
            // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
            return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        }
        else if (value instanceof BeanDefinition) {
            // Resolve plain BeanDefinition, without contained name: use dummy name.
            BeanDefinition bd = (BeanDefinition) value;
            String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
                    ObjectUtils.getIdentityHexString(bd);
            return resolveInnerBean(argName, innerBeanName, bd);
        }
        //下面就是Array,List,Map等属性的注入
        else if (value instanceof ManagedArray) {
            // May need to resolve contained runtime references.
            ManagedArray array = (ManagedArray) value;
            Class<?> elementType = array.resolvedElementType;
            if (elementType == null) {
                String elementTypeName = array.getElementTypeName();
                if (StringUtils.hasText(elementTypeName)) {
                    try {
                        elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                        array.resolvedElementType = elementType;
                    }
                    catch (Throwable ex) {
                        // Improve the message by showing the context.
                        throw new BeanCreationException(
                                this.beanDefinition.getResourceDescription(), this.beanName,
                                "Error resolving array type for " + argName, ex);
                    }
                }
                else {
                    elementType = Object.class;
                }
            }
            return resolveManagedArray(argName, (List<?>) value, elementType);
        }
        else if (value instanceof ManagedList) {
            // May need to resolve contained runtime references.
            return resolveManagedList(argName, (List<?>) value);
        }
        else if (value instanceof ManagedSet) {
            // May need to resolve contained runtime references.
            return resolveManagedSet(argName, (Set<?>) value);
        }
        else if (value instanceof ManagedMap) {
            // May need to resolve contained runtime references.
            return resolveManagedMap(argName, (Map<?, ?>) value);
        }
        else if (value instanceof ManagedProperties) {
            Properties original = (Properties) value;
            Properties copy = new Properties();
            original.forEach((propKey, propValue) -> {
                if (propKey instanceof TypedStringValue) {
                    propKey = evaluate((TypedStringValue) propKey);
                }
                if (propValue instanceof TypedStringValue) {
                    propValue = evaluate((TypedStringValue) propValue);
                }
                if (propKey == null || propValue == null) {
                    throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Error converting Properties key/value pair for " + argName + ": resolved to null");
                }
                copy.put(propKey, propValue);
            });
            return copy;
        }
        else if (value instanceof TypedStringValue) {
            // Convert value to target type here.
            TypedStringValue typedStringValue = (TypedStringValue) value;
            Object valueObject = evaluate(typedStringValue);
            try {
                Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
                if (resolvedTargetType != null) {
                    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                }
                else {
                    return valueObject;
                }
            }
            catch (Throwable ex) {
                // Improve the message by showing the context.
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Error converting typed String value for " + argName, ex);
            }
        }
        else if (value instanceof NullBean) {
            return null;
        }
        else {
            return evaluate(value);
        }
    }
    

    到这呢,就解析完关于set方法的源码分析,这里从上一章AOP那里,主要是组装Advisor相关BeanDefinition的时候,有的放在propertyValues,有的放在constructorArgumentValues。放在propertyValues的,比如DefaultBeanFactoryPointcutAdvisor,会有两个RuntimeBeanReference的propertyValues,通过上面的代码,在populateBean()的时候就将PropertyValues的相关实例注入成功,那么下面就看看构造函数相关的注入。

    2.2)构造函数注入详解
    上一章也提到,AspectJPointcutAdvisor比DefaultBeanFactoryPointcutAdvisor复杂很多。它将AbstractAspectJAdvice放在构造函数中,而AspectJAroundAdvice也复杂,它存在三个构造函数参数,和两个property。
    因为构造函数的使用跟bean实例的创建有关,所以跟构造函数注入相关的,肯定在createBeanInstance()

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //通过supplier创建bean
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        //如果是工厂模式,就通过工厂方法创建bean
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }
    
        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                //如果resolvedConstructorOrFactoryMethod不为空,且存在constructorArgumentsResolved,则autowireConstructor。
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                //通过构造函数创建bean
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //通过默认构造函数创建bean
                return instantiateBean(beanName, mbd);
            }
        }
    
        // Candidate constructors for autowiring?
        //如果在Autowired的时候走的是构造函数AUTOWIRE_CONSTRUCTOR
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }
    
        // Preferred constructors for default construction?
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            return autowireConstructor(beanName, mbd, ctors, null);
        }
    
        // No special handling: simply use no-arg constructor.
        //如果没有特别情况,就通过默认的构造函数创建bean
        return instantiateBean(beanName, mbd);
    }
    //通过构造函数创建bean实例
    public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
            @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
        //先实例化一个BeanWrapperImpl类对象
        BeanWrapperImpl bw = new BeanWrapperImpl();
        this.beanFactory.initBeanWrapper(bw);
    
        Constructor<?> constructorToUse = null;
        ArgumentsHolder argsHolderToUse = null;
        Object[] argsToUse = null;
    
        //如果构造参数不为空就直接使用
        if (explicitArgs != null) {
            argsToUse = explicitArgs;
        }
        else {
            Object[] argsToResolve = null;
            synchronized (mbd.constructorArgumentLock) {
                //获取已缓存解析的构造函数或工厂方法resolvedConstructorOrFactoryMethod
                constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                    // Found a cached constructor...
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            //如果preparedConstructorArguments存在,就通过resolvePreparedArguments将调用BeanDefinitionValueResolver等转化工具进行转换
            //valueResolver.resolveValueIfNecessary()
            if (argsToResolve != null) {
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
            }
        }
    
        //如果缓存的构造器不存在,就说明没有bean进行过解析,需要去关联对应的bean的构造器
        if (constructorToUse == null || argsToUse == null) {
            。。。
            if (candidates == null) {
                Class<?> beanClass = mbd.getBeanClass();
                try {
                    //candidate放的是构造函数
                    candidates = (mbd.isNonPublicAccessAllowed() ?
                            beanClass.getDeclaredConstructors() : beanClass.getConstructors());
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                            "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                }
            }
    
    
            // Need to resolve the constructor.
            获取注入模式
            boolean autowiring = (chosenCtors != null ||
                    mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
            ConstructorArgumentValues resolvedValues = null;
    
            int minNrOfArgs;
            //传入的构造参数不为空,这种构造器最小参数个数个传入的个数
            if (explicitArgs != null) {
                minNrOfArgs = explicitArgs.length;
            }
            else {
                //如果传的构造参数是空的,则从RootBeanDefinition中获取构造器参数,
                        //并解析对应的构造参数然后添加到ConstructorArgumentValues中
                ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                resolvedValues = new ConstructorArgumentValues();
                //resolveConstructorArguments也是通过BeanDefinitionValueResolver进行解析
                minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
            }
    
            AutowireUtils.sortConstructors(candidates);
            int minTypeDiffWeight = Integer.MAX_VALUE;
            Set<Constructor<?>> ambiguousConstructors = null;
            LinkedList<UnsatisfiedDependencyException> causes = null;
    
            //遍历构造函数
            for (Constructor<?> candidate : candidates) {
                Class<?>[] paramTypes = candidate.getParameterTypes();
                。。。
                ArgumentsHolder argsHolder;
                if (resolvedValues != null) {
                    try {
                        String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                        if (paramNames == null) {
                            //如果paramNames是空,则说明参数没有被获取到,则在beanFactory中
                                                //获取用于获取方法参数的ParameterNameDiscoverer对象,然后获取参数名称
                            ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                            if (pnd != null) {
                                paramNames = pnd.getParameterNames(candidate);
                            }
                        }
                        //根据获取到的参数名和已经查到的构造参数和构造参数类型来创建用户创建构造器用的构造参数数组,
                                        //这个数组中包含了原始的参数列表和构造后的参数列表
                                        //调用resolveAutowiredArgument-->beanFactory.resolveDependency()
                        argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                                getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                    }
                    catch (UnsatisfiedDependencyException ex) {
                        。。。
                    }
                }
                else {
                    // Explicit arguments given -> arguments length must match exactly.
                    if (paramTypes.length != explicitArgs.length) {
                        continue;
                    }
                    argsHolder = new ArgumentsHolder(explicitArgs);
                }
    
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                        argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // Choose this constructor if it represents the closest match.
                if (typeDiffWeight < minTypeDiffWeight) {
                    constructorToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousConstructors = null;
                }
                else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                    if (ambiguousConstructors == null) {
                        ambiguousConstructors = new LinkedHashSet<>();
                        ambiguousConstructors.add(constructorToUse);
                    }
                    ambiguousConstructors.add(candidate);
                }
            }
    
            if (constructorToUse == null) {
                if (causes != null) {
                    UnsatisfiedDependencyException ex = causes.removeLast();
                    for (Exception cause : causes) {
                        this.beanFactory.onSuppressedException(cause);
                    }
                    throw ex;
                }
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Could not resolve matching constructor " +
                        "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
            }
            else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Ambiguous constructor matches found in bean '" + beanName + "' " +
                        "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                        ambiguousConstructors);
            }
    
            if (explicitArgs == null) {
                argsHolderToUse.storeCache(mbd, constructorToUse);
            }
        }
        //用上面得到的构造器constructorToUse(无论是从bean对象中获取的还是spring自己构建的)
                    //和参数来反射创建bean实例,并放到BeanWrapperImpl对象中然后返回
        bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
        return bw;
    }
    private Object instantiate(
            String beanName, RootBeanDefinition mbd, Constructor constructorToUse, Object[] argsToUse) {
    
        try {
            InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
            if (System.getSecurityManager() != null) {
                return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                        strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
                        this.beanFactory.getAccessControlContext());
            }
            else {
                 //用上面得到的构造器constructorToUse(无论是从bean对象中获取的还是spring自己构建的)
                            //和参数来反射创建bean实例,并放到BeanWrapperImpl对象中然后返回
                return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean instantiation via constructor failed", ex);
        }
    }
    

    在createArgumentArray的时候,会用到eanFactory.resolveDependency()--->addCandidateEntry()创建dependency的bean,详细分析在Spring IOC(7)DefaultListableBeanFactory

    private ArgumentsHolder createArgumentArray(
            String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
            BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
            boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
    
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        TypeConverter converter = (customConverter != null ? customConverter : bw);
    
        ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
        Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    
        for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
            Class<?> paramType = paramTypes[paramIndex];
            String paramName = (paramNames != null ? paramNames[paramIndex] : "");
            // Try to find matching constructor argument value, either indexed or generic.
            ConstructorArgumentValues.ValueHolder valueHolder = null;
            if (resolvedValues != null) {
                valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
                // If we couldn't find a direct match and are not supposed to autowire,
                // let's try the next generic, untyped argument value as fallback:
                // it could match after type conversion (for example, String -> int).
                if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                    valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
                }
            }
            if (valueHolder != null) {
                // We found a potential match - let's give it a try.
                // Do not consider the same value definition multiple times!
                usedValueHolders.add(valueHolder);
                Object originalValue = valueHolder.getValue();
                Object convertedValue;
                if (valueHolder.isConverted()) {
                    convertedValue = valueHolder.getConvertedValue();
                    args.preparedArguments[paramIndex] = convertedValue;
                }
                else {
                    MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                    try {
                        convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
                    }
                    catch (TypeMismatchException ex) {
                        throw new UnsatisfiedDependencyException(
                                mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                                "Could not convert argument value of type [" +
                                        ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                                        "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                    }
                    Object sourceHolder = valueHolder.getSource();
                    if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                        Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                        args.resolveNecessary = true;
                        args.preparedArguments[paramIndex] = sourceValue;
                    }
                }
                args.arguments[paramIndex] = convertedValue;
                args.rawArguments[paramIndex] = originalValue;
            }
            else {
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                // No explicit match found: we're either supposed to autowire or
                // have to fail creating an argument array for the given constructor.
                if (!autowiring) {
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                            "Ambiguous argument values for parameter of type [" + paramType.getName() +
                            "] - did you specify the correct bean references as arguments?");
                }
                try {
                    //主要是这里调用beanFactory.resolveDependency()实例化dependency
                    Object autowiredArgument = resolveAutowiredArgument(
                            methodParam, beanName, autowiredBeanNames, converter, fallback);
                    args.rawArguments[paramIndex] = autowiredArgument;
                    args.arguments[paramIndex] = autowiredArgument;
                    args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
                    args.resolveNecessary = true;
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
                }
            }
        }
    
        for (String autowiredBeanName : autowiredBeanNames) {
            this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
            if (logger.isDebugEnabled()) {
                logger.debug("Autowiring by type from bean name '" + beanName +
                        "' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
                        " to bean named '" + autowiredBeanName + "'");
            }
        }
    
        return args;
    }
    @Nullable
    protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
            @Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
    
        Class<?> paramType = param.getParameterType();
        if (InjectionPoint.class.isAssignableFrom(paramType)) {
            InjectionPoint injectionPoint = currentInjectionPoint.get();
            if (injectionPoint == null) {
                throw new IllegalStateException("No current InjectionPoint available for " + param);
            }
            return injectionPoint;
        }
        try {
            return this.beanFactory.resolveDependency(
                    new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
        }
        catch (NoUniqueBeanDefinitionException ex) {
            throw ex;
        }
        catch (NoSuchBeanDefinitionException ex) {
            if (fallback) {
                // Single constructor or factory method -> let's return an empty array/collection
                // for e.g. a vararg or a non-null List/Set/Map parameter.
                if (paramType.isArray()) {
                    return Array.newInstance(paramType.getComponentType(), 0);
                }
                else if (CollectionFactory.isApproximableCollectionType(paramType)) {
                    return CollectionFactory.createCollection(paramType, 0);
                }
                else if (CollectionFactory.isApproximableMapType(paramType)) {
                    return CollectionFactory.createMap(paramType, 0);
                }
            }
            throw ex;
        }
    }
    

    相关文章

      网友评论

        本文标题:Spring AOP(5)通过Aspect的BeanDefini

        本文链接:https://www.haomeiwen.com/subject/babgoktx.html