【Spring学习笔记】之【3.1 DI的使用 三】

3.1.8  内部Bean定义

内部Bean就是在<property>或<constructor-arg>内通过<bean>标签定义的Bean,该Bean不管是否指定id或name,该Bean都会有唯一的匿名标识符,而且不能指定别名,该内部Bean对其他外部Bean不可见,具体配置如下:

(1)让我们写个例子测试一下吧,具体配置文件如下:


java代码:
查看 复制到剪贴板 打印
  1. <bean id="bean"class="cn.javass.spring.chapter3.bean.HelloApiDecorator">  

  2. <property name="helloApi">  

  3. <bean id="helloApi"class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>  

  4. </property>  

  5. </bean>  


(2)测试代码(cn.javass.spring.chapter3.DependencyInjectTest.testInnerBeanInject):


java代码:
查看 复制到剪贴板 打印
  1. @Test

  2. publicvoid testInnerBeanInject() {  

  3. ApplicationContext context =  

  4. new ClassPathXmlApplicationContext("chapter3/innerBeanInject.xml");  

  5. HelloApi bean = context.getBean("bean", HelloApi.class);  

  6. bean.sayHello();  

  7. }  


3.1.9  处理null值

       Spring通过<value>标签或value属性注入常量值,所有注入的数据都是字符串,那如何注入null值呢?通过“null”值吗?当然不是因为如果注入“null”则认为是字符串。Spring通过<null/>标签注入null值。即可以采用如下配置方式:

3.1.10 对象图导航注入支持

      所谓对象图导航是指类似a.b.c这种点缀访问形式的访问或修改值。Spring支持对象图导航方式依赖注入。对象图导航依赖注入有一个限制就是比如a.b.c对象导航图注入中a和b必须为非null值才能注入c,否则将抛出空指针异常。

      Spring不仅支持对象的导航,还支持数组、列表、字典、Properties数据类型的导航,对Set数据类型无法支持,因为无法导航。

数组和列表数据类型可以用array[0]、list[1]导航,注意”[]”里的必须是数字,因为是按照索引进行导航,对于数组类型注意不要数组越界错误。

字典Map数据类型可以使用map[1]、map[str]进行导航,其中“[]”里的是基本类型,无法放置引用类型。

      让我们来练习一下吧。首先准备测试类,在此我们需要三个测试类,以便实现对象图导航功能演示:

       NavigationC类用于打印测试代码,从而观察配置是否正确;具体类如下所示:


java代码:
查看 复制到剪贴板 打印
  1. package cn.javass.spring.chapter3.bean;  

  2. publicclass NavigationC {  

  3. publicvoid sayNavigation() {  

  4.        System.out.println("===navigation c");  

  5.    }  

  6. }  


   NavigationB类,包含对象和列表、Properties、数组字典数据类型导航,而且这些复合数据类型保存的条目都是对象,正好练习一下如何往复合数据类型中注入对象依赖。具体类如下所示:


java代码:
查看 复制到剪贴板 打印
  1. package cn.javass.spring.chapter3.bean;  

  2. import java.util.List;  

  3. import java.util.Map;  

  4. import java.util.Properties;  

  5. publicclass NavigationB {  

  6. private NavigationC navigationC;  

  7. private List<NavigationC> list;  

  8. private Properties properties;  

  9. private NavigationC[] array = new NavigationC[1];  

  10. private Map<String, NavigationC> map;  

  11. //由于setter和getter方法占用太多空间,故省略,大家自己实现吧

  12. }  


       NavigationA类是我们的前端类,通过对它的导航进行注入值,具体代码如下:


java代码:
查看 复制到剪贴板 打印
  1. package cn.javass.spring.chapter3.bean;  

  2. publicclass NavigationA {  

  3. private NavigationB navigationB;  

  4. publicvoid setNavigationB(NavigationB navigationB) {  

  5. this.navigationB = navigationB;  

  6.    }  

  7. public NavigationB getNavigationB() {  

  8. return navigationB;  

  9.    }  

  10. }  


       接下来该进行Bean定义配置(resources/chapter3/navigationBeanInject.xml)了,首先让我们配置一下需要被导航的数据,NavigationC和NavigationB类,其中配置NavigationB时注意要确保比如array字段不为空值,这就需要或者在代码中赋值如“NavigationC[] array = new NavigationC[1];”,或者通过配置文件注入如“<list&amp;gt;</list>”注入一个不包含条目的列表。具体配置如下:


java代码:
查看 复制到剪贴板 打印
  1. <bean id="c"class="cn.javass.spring.chapter3.bean.NavigationC"/>  

  2. <bean id="b"class="cn.javass.spring.chapter3.bean.NavigationB">  

  3. <property name="list"><list></list></property>  

  4.    <property name="map"><map></map></property>  

  5.    <property name="properties"><props></props></property>  

  6. </bean>  


        配置完需要被导航的Bean定义了,该来配置NavigationA导航Bean了,在此需要注意,由于“navigationB”属性为空值,在此需要首先注入“navigationB”值;还有对于数组导航不能越界否则报错;具体配置如下:


java代码:
查看 复制到剪贴板 打印
  1. <bean id="a"class="cn.javass.spring.chapter3.bean.NavigationA">  

  2. <!-- 首先注入navigatiionB 确保它非空 -->  

  3. <property name="navigationB" ref="b"/>  

  4. <!-- 对象图导航注入 -->  

  5. <property name="navigationB.navigationC" ref="c"/>  

  6. <!-- 注入列表数据类型数据 -->  

  7. <property name="navigationB.list[0]" ref="c"/>  

  8. <!-- 注入map类型数据 -->  

  9. <property name="navigationB.map[key]" ref="c"/>  

  10. <!-- 注入properties类型数据 -->  

  11. <property name="navigationB.properties[0]" ref="c"/>  

  12. <!-- 注入properties类型数据 -->  

  13. <property name="navigationB.properties[1]" ref="c"/>  

  14. <!-- 注入数组类型数据 ,注意不要越界-->  

  15. <property name="navigationB.array[0]" ref="c"/>  

  16. </bean>  


       配置完毕,具体测试代码在cn.javass.spring.chapter3. DependencyInjectTest,让我们看下测试代码吧:


java代码:
查看 复制到剪贴板 打印
  1. //对象图导航

  2. @Test

  3. publicvoid testNavigationBeanInject() {  

  4. ApplicationContext context =  

  5. new ClassPathXmlApplicationContext("chapter3/navigationBeanInject.xml");        

  6. NavigationA navigationA = context.getBean("a", NavigationA.class);  

  7. navigationA.getNavigationB().getNavigationC().sayNavigation();  

  8. navigationA.getNavigationB().getList().get(0).sayNavigation();  

  9. navigationA.getNavigationB().getMap().get("key").sayNavigation();  

  10. navigationA.getNavigationB().getArray()[0].sayNavigation();  

  11. ((NavigationC)navigationA.getNavigationB().getProperties().get("1"))  

  12. .sayNavigation();        

  13. }  



      测试完毕,应该输出5个“===navigation c”,是不是很简单,注意这种方式是不推荐使用的,了解一下就够了,最好使用3.1.5一节使用的配置方式。


3.1.11配置简写

让我们来总结一下依赖注入配置及简写形式,其实我们已经在以上部分穿插着进行简化配置了:


一、构造器注入:

1)常量值

简写:<constructor-arg index="0" value="常量"/>

全写:<constructor-arg index="0"><value>常量</value></constructor-arg>

2)引用

简写:<constructor-arg index="0" ref="引用"/>

全写:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>


二、setter注入:

      1)常量值

       简写:<property name="message" value="常量"/>

       全写:<property name="message"><value>常量</value></ property>

      2)引用

       简写:<property name="message" ref="引用"/>

       全写:<property name="message"><ref bean="引用"/></ property>

      3)数组:<array>没有简写形式

      4)列表:<list>没有简写形式

      5)集合:<set>没有简写形式

      6)字典

         简写:<map>

            <entry key="键常量" value="值常量"/>

            <entry key-ref="键引用" value-ref="值引用"/>

           </map>

        全写:<map>

            <entry><key><value>键常量</value></key><value>值常量</value></entry>

            <entry><key><ref bean="键引用"/></key><ref bean="值引用"/></entry>

          </map>

      7)Properties:没有简写形式


三、使用p命名空间简化setter注入:

      使用p命名空间来简化setter注入,具体使用如下:


java代码:
查看 复制到剪贴板 打印
  1. <?xml version="1.0" encoding="UTF-8"?>  

  2. <beans  xmlns="http://www.springframework.org/schema/beans"

  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  4.        xmlns:p="http://www.springframework.org/schema/p"

  5.        xsi:schemaLocation="  

  6.           http://www.springframework.org/schema/beans

  7.           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  8. <bean id="bean1"class="java.lang.String">  

  9.        <constructor-arg index="0" value="test"/>  

  10.    </bean>  

  11. <bean id="idrefBean1"class="cn.javass.spring.chapter3.bean.IdRefTestBean"

  12. p:id="value"/>  

  13. <bean id="idrefBean2"class="cn.javass.spring.chapter3.bean.IdRefTestBean"

  14. p:id-ref="bean1"/>  

  15. </beans>  

  • xmlns:p="http://www.springframework.org/schema/p" :首先指定p命名空间;

  • <bean id="……" class="……" p:id="value"/> 常量setter注入方式,其等价于<property name="id" value="value"/>;

      • <bean id="……" class="……" p:id-ref="bean1"/> 引用setter注入方式,其等价于<property name="id" ref="bean1"/>。




你可能感兴趣的:(spring,spring学习笔记,Spring教程)