关于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)方法。

posted @ 2017-11-23 19:05  四少啊  阅读(2398)  评论(0编辑  收藏  举报