zoukankan      html  css  js  c++  java
  • 关于spring的自动注入

    关于spring的自动注入

    spring里面可以设置BeanDefinition自动注入类型,默认为AUTOWIRE_NO(不进行自动注入)。mybatis里面的扫描接口生成MapperFactoryBean的时候设置了

     definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
    

    他这里是为了按类型自动注入SqlSessionFactory或者SqlSessionTemplate。

    spring构造bean的时候会进行填充属性,调用了如下方法:

    	protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw);
    

    内部有一段逻辑:

    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
    				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
    			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    
    			// Add property values based on autowire by name if applicable.
    			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
    				autowireByName(beanName, mbd, bw, newPvs);
    			}
    
    			// Add property values based on autowire by type if applicable.
    			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
    				autowireByType(beanName, mbd, bw, newPvs);
    			}
    
    			pvs = newPvs;
    		}
    

    前面MapperFactoryBean的BeanDefinition已经设置成AUTOWIRE_BY_TYPE,所以会调用autowireByType方法,该方法内部逻辑为获取当前bean的所有PropertyDescriptor,并且过滤出包含有WriteMethod的PropertyNames。

    获取一个bean的PropertyDescriptor示例代码如下:

    public class IntrospectorTest {
    
        /**
         * PropertyDescriptor依赖字段的set和get方法
         * 没有对应的set和get方法则没有对应的read和write方法
         *
         * 依赖于set和get方法,跟具体的字段名没关系
         *
         * @throws IntrospectionException
         */
        @Test
        public void testPropertyDescriptors() throws IntrospectionException {
            BeanInfo beanInfo = Introspector.getBeanInfo(IntrospectorTest.class);
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                if (pd.getName().equals("class")) {
                    continue;
                }
                System.out.println(pd.getName());
                System.out.println(pd.getReadMethod());
                System.out.println(pd.getWriteMethod());
                System.out.println("********");
            }
        }
    
        public void setName(String name){}
    
    }
    

    然后从获取的PropertyNames迭代,获取相应WriteMethod的入参类型,并从spring容器获取相应类型的Bean,如果获取到设置到MutablePropertyValues里。

    最后调用方法:

    applyPropertyValues(beanName, mbd, bw, pvs);
    

    迭代MutablePropertyValues的PropertyValue,内部最终调用构造Bean的setXxx方法进行注入。

    总结:spring的PropertyValues注入都是通过setXxx方法设置,比如xml配置的property或者BeanDefinition的getPropertyValues().add(key,value)方法。

  • 相关阅读:
    Pandas Statistical Functions
    pyspark 记录
    走出浮躁的泥沼:学会享受学习过程的乐趣
    寻找知识不变的那部分
    走出浮躁的泥沼:把一件事做到某种境界
    走出浮躁的泥沼:为什么会浮躁
    对抗拖延症最直接有效的方法
    实施“番茄工作法”需要注意的一些细节
    东西学了容易忘?学会跟踪你的知识
    再谈读书与信息的获取、沉淀
  • 原文地址:https://www.cnblogs.com/yaojf/p/7886503.html
Copyright © 2011-2022 走看看