源码如下
【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、我寻思该功能肯定有特殊的应用场景,暂时不清楚用在哪里比较有优势