Spring不为人知的功能点-PropertyTokenHolder

阅读getBean源码的时候发现PropertyTokenHolder这个类,觉得很诡异,仔细研究了下,发现了一个不为人知的功能点

源码入口

【BeanWrapperImpl】
public void setPropertyValue(PropertyValue pv) throws BeansException {
        PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
        if (tokens == null) {
            String propertyName = pv.getName();
            BeanWrapperImpl nestedBw = null;
            try {
                nestedBw = getBeanWrapperForPropertyPath(propertyName);
            }
            catch (NotReadablePropertyException ex) {
                throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                        "Nested property in path '" + propertyName + "' does not exist", ex);
            }
            tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
            if (nestedBw == this) {
                pv.getOriginalPropertyValue().resolvedTokens = tokens;
            }
            nestedBw.setPropertyValue(tokens, pv);
        }
        else {
            setPropertyValue(tokens, pv);
        }
    }

实例说明

对比前一篇关于Spring不为人知的功能点,重点关注"myRef.name[0]"这个属性

<?xml version="1.0" encoding="GB2312"?>
 
<beans  
 xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" default-autowire="byName">
 
    <bean id="aop" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" >
    </bean>
    <aop:config >
    </aop:config>
    <bean id="greetingService" class="GreetingServiceImpl" >
        <property name="myRef" ref="myRef" />
        <property name="myRef.name[0]" value="chenshuai123" />
        <property name="greeting" value="Hello karry!" />
        <property name="count" value ="12" />
        <property name="urls" value ="tmp*.xml" />
    </bean>
 
    <bean id="count" class="Count">
        <property name="greetingService" ref="greetingService" />
    </bean>
 
    <bean id="myRef" class="MyRef">
        <property name="name[0]" value="chenshuai" />
        <property name="sex" value="male" />
    </bean>
 
    <bean id="advice" class="Advice">
    </bean>
 
    <bean id="adviceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
        <property name="advice" ref="advice" />
        <property name="expression" value="execution(* *.sayGreeting(..))" />
    </bean>
 
</beans>

这里就不列出场景一、二和三了,了解了前一篇关于这点的原理之后,其实结果是一样的

public class testMain {
    public static void main(String[] args) {
        //final ApplicationContext factory = new  ClassPathXmlApplicationContext("myBeans.xml");
        final BeanFactory factory = new XmlBeanFactory(new ClassPathResource("myBeans.xml"));
        //BeanPostProcessor aop = (BeanPostProcessor) factory.getBean("aop");
        //factory.addBeanPostProcessor(aop);
        MyRef myRef =  (MyRef) factory.getBean("myRef");
        System.out.println(myRef.getName());
        GreetingService greetingService = (GreetingService) factory.getBean("greetingService");
        Resource[] urls = greetingService.getUrls();
        greetingService.sayGreeting();
        //MyRef myRef =  (MyRef) factory.getBean("myRef");
        //System.out.println(myRef.getName());
    }
}

输出结果:

[chenshuai]
Hello karry!12chenshuai123

总结:

一、旨在说明Spring对于set、list、map等需求的一些功能点,当然支持多个key的操作了,具体的操作参考上面的源码去实现,不难。

二、list在类里面一定要实例化好,因为依赖注入可不管你list的实例化的。

三、注意区别该功能点和list、map直接属性注入的区别。


你可能感兴趣的:(spring,bean,IOC)