Spring不为人知的功能点-nestedBw

源码如下

【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);
        }
    }


这里的nestedBw作何解释,嵌套的Bw功能,自己写了个例子来诠释上面的功能点,如下(大体只需要关注greetingService):

<?xml version="1.0" encoding="GB2312"?>
 
<beans  xmlns="<a href=" 
xmlns:xsi="<a href=" 
xmlns:aop="<a href=" 
xmlns:p="<a href="http://www.springframework.org/schema/p"
 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" 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" 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>

[GreetingServiceImpl]
public class GreetingServiceImpl implements GreetingService, BeanPostProcessor {
......
    public void sayGreeting() {
        String n = count;
        System.out.println(greeting+n+myRef.getName());
    }

场景一:

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());
    }
}

输出结果为:

Hello karry!12chenshuai123
chenshuai123

场景二:

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

场景三:

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());
    }
}

输出结果为:

OK
OK
chenshuai123
before
before
Hello karry!12chenshuai123

猜猜这次结果为什么是这样呢?

总结

1、只做了一次set,嵌套只对最后一个Bean做set处理

2、不推荐使用嵌套的Bean,因为会因为getBean的次序破坏Bean的唯一性。

3、注意区别嵌套Bean和内部Bean

4、我寻思该功能肯定有特殊的应用场景,暂时不清楚用在哪里比较有优势



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