引用其他Bean
组件应用程序的Bean经常需要相互协作以完成应用程序的功能,所以要求Bean能够相互访问,就必须在Bean配置文件中指定Bean的引用。在Bean的配置文件中可以用过<ref>元素或者ref属性为Bean的属性或构造器参数指定对Bean的引用。也可以在属性或者构造器里包含Bean的声明,这样的Bean称为内部Bean。具体看代码,在之前的Student类上新增Book类,(一个学生有一本书)。代码如下:
Book.java
package com.lql.spring01; /** * @author: lql * @date: 2019.10.11 * Description: * Created with IntelliJ IDEA */ public class Book { private String name; private double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }
Student.java
package com.lql.spring01;/** * @author: lql * @date: 2019.09.24 * Description: */ public class Student { private String name; private Integer age; private Book book; public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然后在applicationContext.xml的配置文件中配置Book类的bean;
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean id:标识 class:类路径 name:属性名,注意是针对set方法的属性名,不是变量的属性名 value:属性值 --> <bean id="student" class="com.lql.spring01.Student"> <property name="name" value="lql"></property> <property name="age" value="18"></property> <property name="book" ref="book"></property> <!--<property name="book"> <ref bean="book"></ref> </property>--> </bean> <bean id="book" class="com.lql.spring01.Book"> <property name="name" value="三国演义"></property> <property name="price" value="79.9"></property> </bean> </beans>
代码中就是使用<ref>元素或者ref属性来引用的示例,测试是没问题的:
public void Hello() { System.out.println("Hello :" + this.getName() + ",Book:" + this.book.getName()); } public static void main(String[] args) {//创建IOC容器 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean Student student = app.getBean("student", Student.class); //调用方法 student.Hello(); }
//输出:Hello :lql,Book:三国演义
内部Bean
当Bean的实例仅仅给一个特定的属性使用时,可以将其声明为内部Bean,内部Bean声明直接包含<property>或<constructor-arg>元素里,不需要设置任何的id或name属性,内部Bean不能使用在任何其他地方。
实际很简单,配置更改如下:
<bean id="student" class="com.lql.spring01.Student"> <property name="name" value="lql"></property> <property name="age" value="18"></property> <!--内部bean--> <property name="book"> <bean class="com.lql.spring01.Book"> <property name="price" value="100.0"></property> <property name="name" value="时间简史"></property> </bean> </property> </bean>
测试也是没问题的,这里省略打印。
NULL值和级联属性
可以使用专用的<null/>元素标签为Bean的字符串或其它对象类型的属性注入null值(意义不大,了解知道有这么回事就行了),当然Spring也支持级联属性的配置。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean id:标识 class:类路径 name:属性名,注意是针对set方法的属性名,不是变量的属性名 value:属性值 --> <bean id="student" class="com.lql.spring01.Student"> <property name="name" value="lql"></property> <property name="age" value="18"></property> <property name="book"> <null/> </property> </bean> <bean id="book" class="com.lql.spring01.Book"> <property name="name" value="三国演义"></property> <property name="price" value="79.9"></property> </bean> </bean>
这样一来,book的引用就是null。级联属性的代码如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean id:标识 class:类路径 name:属性名,注意是针对set方法的属性名,不是变量的属性名 value:属性值 --> <bean id="student" class="com.lql.spring01.Student"> <property name="name" value="lql"></property> <property name="age" value="18"></property> <property name="book" ref="book"></property> <property name="book.price" value="19.9"></property> <property name="book.name" value="java从入门到放弃"></property> </bean> <bean id="book" class="com.lql.spring01.Book"> <property name="name" value="三国演义"></property> <property name="price" value="79.9"></property> </bean> </bean>
打印结果为:Hello :lql,Book:java从入门到放弃,而非三国演义了。需要注意的是一定要提供setter()。并且我先给book赋值的后调级联属性的,<property name="book" ref="book"></property>,如果没有先引用直接使用级联属性可行不可行呢?答案是否定的,在Struts2里面是支持的,但是Spring是不支持。它会报:Value of nested property 'book' is null。(但是很多情况下也用不到级联属性,知道了解就行了)。
集合属性
在Spring中可以通过一组内置的xml标签来配置集合属性(例如:<list>,<set>,<map>等),配置java.util.List类型的属性,需要指定<list>标签,内部可以使用<value>指定简单的常量值,也可以通过<ref>指定对其他Bean的引用,通过<null/>指定空元素,甚至可以内嵌其他集合。当然,数组也可以使用<list>,<array>。代码如下:先建ListDemo类
package com.lql.spring01; import java.util.List; /** * @author: lql * @date: 2019.10.11 * Description: * Created with IntelliJ IDEA */ public class ListDemo { private List<String> list; public void setList(List<String> list) { this.list = list; } public List<String> getList() { return list; } }
配置文件如下:需要为ListDemo.java的list属性赋值
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="list" class="com.lql.spring01.ListDemo"> <property name="list"> <list value-type="java.lang.String"> <value>红色</value> <value>白色</value> <value>黑色</value> <value>还原色</value> </list> </property> </bean> </bean>
测试代码和结果:
public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml"); ListDemo list = app.getBean("list", ListDemo.class); list.getList().forEach(System.out::println); }
//结果: 红色 白色 黑色 还原色
java.util.Set需要使用<set>标签,定义方式与List一样。这里略,(set不允许重复)
java.util.map通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签,每个条目包含一个键和一个值,需要注意几点:
①:必须在<key>标签里面定义key.
②:因为键和值的类型没有限制,所以可以自由地为它们指定<value>,<ref>,<bean>,<null>元素。
③:可以将Map的键和值作为<entry>的属性定义。简单常量使用key和value定义,Bean引用通过key-ref和value-ref属性定义
④:使用<props>定义java.util.properties,(properties是hashtable的子类)该标签使用多个<prop>作为子标签,每个<prop>标签必须定义key属性。
代码如下,简单的形式定义:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="list" class="com.lql.spring01.ListDemo"> <property name="list"> <list value-type="java.lang.String"> <value>红色</value> <value>白色</value> <value>黑色</value> <value>还原色</value> </list> </property> <property name="set"> <set value-type="java.lang.Integer"> <value>1</value> <value>2</value> <value>3</value> <value>4</value> <value>5</value> <value>3</value> </set> </property> <property name="map"> <map> <entry key="壹"> <value>1</value> </entry> <entry key="贰"> <value>2</value> </entry> </map> </property> </bean> </beans>
测试结果是可行的:
public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml"); ListDemo list = app.getBean("list", ListDemo.class);
//list list.getList().forEach(System.out::println); System.out.println("====================");
//set list.getSet().forEach(System.out::println); System.out.println("===================="); //map Map<String, Integer> map = list.getMap(); map.forEach((x,y)-> System.out.println(x + "====" + y)); }
//输出:壹====1,贰====2
接下来试试properties类:
先定义一个PropertiesDemo.java
package com.lql.spring01; import java.util.Properties; /** * @author: lql * @date: 2019.10.11 * Description: * Created with IntelliJ IDEA */ public class PropertiesDemo { private Properties properties; public void setProperties(Properties properties) { this.properties = properties; } public Properties getProperties() { return properties; } }
applicationContext.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="properties" class="com.lql.spring01.PropertiesDemo"> <property name="properties"> <props> <prop key="壹">1</prop> <prop key="贰">2</prop> <prop key="叁">3</prop> </props> </property> </bean> </bean>
测试代码和结果如下:
public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); PropertiesDemo properties = app.getBean("properties", PropertiesDemo.class); properties.getProperties().forEach((x,y) -> System.out.println(x + "==" + y)); }
//结果:叁==3 壹==1 贰==2
配置单独集合Bean,以供引用
拿之前的List来说,applicationContext.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <util:list id="reList"> <value>红色</value> <value>黄色</value> <value>黑色</value> <value>还原色</value> </util:list> <bean id="list" class="com.lql.spring01.ListDemo"> <property name="list" ref="reList"></property> </bean> </bean>
需要注意的是引入util头,上图已经加粗显示。测试还是没有问题的:
public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml"); ListDemo list = app.getBean("list", ListDemo.class); list.getList().forEach(System.out::println); }
//结果 红色 黄色 黑色 还原色
P命名空间
同样,先引入P的头。加粗
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:P="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean id="stu" class="com.lql.spring01.Student" P:name="张四" P:age="18" P:book-ref="book"></bean> </bean>
测试结果:Hello :张四,Book:java从入门到放弃。