【目录】
3.1 XML文件最基本的元素:Bean元素
3.1.1 Bean元素基本属性
3.1.2 Bean标签创建方式
3.1.3 Bean的生命周期
3.2 Bean元素的注入方式
3.2.1 set方法属性注入
3.2.2 构造器参数注入
3.2.3 注入复杂类型
3.1 XML文件最基本的元素:Bean元素
Bean元素:交由Spring管理的对象都要配置在bean标签中。
<bean>:原意是“豆子”,在Spring中,可以认为一个bean就是一个对象。
3.1.1 Bean元素基本属性
示例代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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元素 -->
<bean id="hello" name="hello1,hello2" class="com.test.HelloWorld" scope="prototype">
<!-- 属性配置 -->
<property name="name" value="hhhhh" />
</bean>
</beans>
具体说明:
- id:bean的名称(对象的名称),在应用程序中,可以根据id值得到配置对象。id的名字必须满足XML的命名规范,不能包含特殊字符或中文,习惯上会使用接口的名字小写。注意:id名在整个Spring的配置文件中,必须唯一。
- name:为id创建一个或多个别名,可以包含特殊符号。
注意:id和name都可以指定多个名字,名字之间可用逗号、分号、或者空格间隔。
- class:是实现类的全名(填写创建对象所在类的全路径),Spring工厂会自动根据该类型名字,采用反射机制来得到具体的类的类型。
- scope:bean的作用范围。有以下5个常用属性值:
(1)singleton:默认值,表示整个IOC容器共享一个Bean,也就是说每次说每次通过getBean获取的bean都是同一个。
(2)prototype:每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
(3)request:在web项目中,创建对象并把对象放到request域里面,每次HTTP请求将会生成各自的bean实例。
(4)session :在web项目中,创建对象并把对象放到到session域中,每次会话请求对应一个bean实例。
(5)globalSession:在web项目中,应用在prolet环境,如果没有prolet环境那么globalSession相当于session。一般用于全局session共享账号。
补充:延迟加载
3.1.2 Bean标签创建方式
- 空参构造:最常用的创建方式。
过程很简单,就是在类中创建一个无参数的构造方法。
例如:
public class User {
public User() {
}
}
一般来说,如果不写无参数的参构造方法,也没有关系,因为在类中会默认有一个隐藏的无参构造方法(不显示在代码中)。
但是注意! 如果你在类中定义了带参的构造方法,那么这个类默认的无参的构造方法没有了,需要手动加上去才行。——这牵涉到我们后面的一个知识点:如果采用构造方法的注入方式(后面讲解三种注入方式),就必须把无参数的参构造方法写出来。不然就会报错误:No default constructor found......
所以这里推荐在编写代码时,把无参数的参构造方法都写出来。
- 静态工厂
- 实例工厂
静态工厂和实例工厂的更多内容推荐看这里Spring创建Bean的三种方式的使用和区别。
- FactoryBean方式:源码底层用的多。不作详细介绍了。只需要区别好BeanFactory和FactoryBean:
BeanFactory:是一个工厂(其实是构建了一个spring上下文的环境,容器),用来管理和获取很多Bean对象,
FactoryBean:是一个Bean生成工具,是用来获取一种类型对象的Bean,它是构造Bean实例的一种方式。
总结:以上四种,第一种最常用,第二、三、一些框架初始化的时候用的多、第四种spring底层用的多。
3.1.3 Bean的生命周期
通过 init-method属性 指定初始化的方法。
通过 destroy-method属性 指定销毁对象的方法 。
3.2 Bean元素的注入方式
Bean元素的注入有三种方法,分别是set方法属性注入、构造器参数注入、接口注入 。
(Spring 框架规范中通过配置文件配置的方式,只支持set方法属性注入和构造器参数注入,不支持接口注入,所以这里只讲解前两种注入方式。)
注入类型有值类型(八大基本数据类型)、引用类型(String、自定义对象等)和复杂类型(Array、List、Set、Map、Properties)。
3.2.1 set方法属性注入
在类中加set方法,然后在配置文件中用<property>标签注入bean即可。
(用此方法展示注入值类型和引用类型,后续方法中不再演示。注入复杂类型在3.2.3单独介绍。)
下面开始演示。
1.注入值类型。代码如下。
实体类User.java:
package user;
public class User {
private Integer u_id;
private String u_username;
private String u_password;
//这里是空参构造
public User() {
}
public Integer getU_id() {
return u_id;
}
public void setU_id(Integer u_id) {
this.u_id = u_id;
}
public String getU_username() {
return u_username;
}
public void setU_username(String u_username) {
this.u_username = u_username;
}
public String getU_password() {
return u_password;
}
public void setU_password(String u_password) {
this.u_password = u_password;
}
@Override
public String toString() {
return "User [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password
+ "]";
}
}
配置文件applicationContext_Injection.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将user对象交给spring管理,并用value注入值类型 -->
<bean name="user" class="user.User">
<property name="u_id" value="1"/>
<property name="u_username" value="set注入-值类型"/>
<property name="u_password" value="123"/>
</bean>
</beans>
测试类 Test_Injection.java:
package user;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_Injection {
@Test
public void Test() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_Injection.xml");
User u1 = (User) ac.getBean("user");
System.out.println(u1);
//关闭容器
ac.close();
}
}
进行测试。
测试结果2.注入引用类型。
在刚刚的工程中新建一个Pet.java,代码如下。
Pet.java:
package user;
public class Pet {
//宠物类型 猫 狗
private String petType;
//宠物的颜色
private String color;
public String getPetType() {
return petType;
}
public void setPetType(String petType) {
this.petType = petType;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Pet [petType=" + petType + ", color=" + color + "]";
}
}
在User.java里加入宠物字段。
User.java:
package user;
public class User {
private Integer u_id;
private String u_username;
private String u_password;
//这里是空参构造
public User() {
}
private Pet u_pet;
public Pet getU_pet() {
return u_pet;
}
public void setU_pet(Pet u_pet) {
this.u_pet = u_pet;
}
public Integer getU_id() {
return u_id;
}
public void setU_id(Integer u_id) {
this.u_id = u_id;
}
public String getU_username() {
return u_username;
}
public void setU_username(String u_username) {
this.u_username = u_username;
}
public String getU_password() {
return u_password;
}
public void setU_password(String u_password) {
this.u_password = u_password;
}
@Override
public String toString() {
return "User [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password + ", u_pet=" + u_pet
+ "]";
}
}
修改配置文件。
applicationContext_Injection.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将pet对象-dog交给spring管理,并用value注入值类型 -->
<bean name="dog" class="user.Pet">
<property name="PetType" value="二哈"/>
<property name="color" value="灰灰的"/>
</bean>
<!-- 将user对象交给spring管理 -->
<bean name="user" class="user.User">
<!-- 注入值类型 -->
<property name="u_id" value="1"/>
<property name="u_username" value="set注入-引用类型"/>
<property name="u_password" value="123"/>
<!-- 用ref注入引用类型 -->
<property name="u_pet" ref="dog"/>
</bean>
</beans>
进行测试。
测试结果3.2.2 构造器参数注入
首先在类中编写一个带参数的构造方法,然后在配置文件中用<constructor-arg>标签注入bean即可。
下面开始演示。
在刚刚的工程中修改User.java,添加一个带参数(String u_username, Pet u_pet)的构造方法。
User.java:
package user;
public class User {
private Integer u_id;
private String u_username;
private String u_password;
//这里是空参构造
public User() {
}
//带参数的构造方法
public User(String u_username, Pet u_pet) {
this.u_username = u_username;
this.u_pet = u_pet;
}
private Pet u_pet;
public Pet getU_pet() {
return u_pet;
}
public void setU_pet(Pet u_pet) {
this.u_pet = u_pet;
}
public Integer getU_id() {
return u_id;
}
public void setU_id(Integer u_id) {
this.u_id = u_id;
}
public String getU_username() {
return u_username;
}
public void setU_username(String u_username) {
this.u_username = u_username;
}
public String getU_password() {
return u_password;
}
public void setU_password(String u_password) {
this.u_password = u_password;
}
@Override
public String toString() {
return "User [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password + ", u_pet=" + u_pet
+ "]";
}
}
修改配置文件。
applicationContext_Injection.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将pet对象-dog交给spring管理,并用value注入值类型 -->
<bean name="dog" class="user.Pet">
<property name="PetType" value="二哈"/>
<property name="color" value="灰灰的"/>
</bean>
<!-- 将user对象交给spring管理 -->
<bean name="user" class="user.User">
<property name="u_id" value="1"/>
<property name="u_username" value="set注入-引用类型"/>
<property name="u_password" value="123"/>
<!-- 用ref注入引用类型 -->
<property name="u_pet" ref="dog"/>
</bean>
<!--构造器参数注入 -->
<bean name="user1" class="user.User">
<constructor-arg name="u_username" value="构造器参数注入" />
<constructor-arg name="u_pet" ref="dog"/>
</bean>
</beans>
修改测试类。
Test_Injection.java:
package user;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_Injection {
@Test
public void Test() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_Injection.xml");
User u1 = (User) ac.getBean("user1");
System.out.println(u1);
//关闭容器
ac.close();
}
}
进行测试。
测试结果补充:
我们知道,在一个类里,可以进行方法的重载( 重载与重写的区别),构造方法可以有多个。我们怎么让bean精准定位到某一个构造方法呢?这就要用到<constructor-arg>标签的type和index属性了。
- 构造方法参数不同时,用type指定一个不同参数的类型,就可以定位构造方法。
( 有多个构造方法,却不使用type,那么就会自动定位到第一个构造方法。) - 构造方法参数相同,位置不同时,用type和index可以共同指定某个参数的位置(从构造函数第一个参数开始index+,第一个参数的index=0),从而定位构造方法。
(只使用type或index的其中一个——只用type,会定位到更新的那一个构造方法;而index无法单独使用。)
【演示】
修改User.java,添加一个与方法1参数不同的方法2。代码片段如下:
//不同参数的构造
//方法1
public User(String u_username, Pet u_pet) {
System.out.println("方法1 String, Pet");
this.u_username = u_username;
this.u_pet = u_pet;
}
//方法2
public User(Integer u_username, Pet u_pet) {
System.out.println("方法2 Integer, Pet");
this.u_username = u_username.toString();
this.u_pet = u_pet;
}
修改配置文件片段,指定type=Integer。同时,把value改成66,因为要传一个Integer类型的值。
<bean name="user1" class="user.User">
<constructor-arg name="u_username" value="66" type="java.lang.Integer" />
<constructor-arg name="u_pet" ref="dog"/>
</bean>
运行结果
修改User.java,添加一个与方法2参数相同,位置不同的方法3。代码片段如下:
//方法1
public User(String u_username, Pet u_pet) {
System.out.println("方法1 String, Pet");
this.u_username = u_username;
this.u_pet = u_pet;
}
//方法2
public User(Integer u_username, Pet u_pet) {
System.out.println("方法2 Integer, Pet");
this.u_username = u_username.toString();
this.u_pet = u_pet;
}
//方法3
public User(Pet u_pet, Integer u_username) {
System.out.println("方法3 Pet, Integer ");
this.u_username = u_username.toString();
this.u_pet = u_pet;
}
不修改配置文件,仍然只指定type=Integer,可以看到运行结果,定位到方法3而非方法2。
定位到更新的方法3而非方法2配置文件片段,指定type=Integer和index=0。
<bean name="user1" class="user.User">
<constructor-arg name="u_username" value="66" type="java.lang.Integer" index="0" />
<constructor-arg name="u_pet" ref="dog"/>
</bean>
运行。
指定到方法23.2.3 注入复杂类型
注入复杂类型也就是注入集合类型 (Array、List、Set、Map、Properties),属于了解内容,在使用时查看即可。
作用:主要用于框架整合配置。
Spring为集合提供了对应的标签:
<array>注入 array元素
<list> 注入 list元素
<set> 注入 set元素
<map> 注入 map元素
<props> 注入 properties 元素 (hashtable类的子类,是特殊的map,key和value都是String )
下面给出参考代码。
集合类代码如下:
package com.sikiedu.bean;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyCollection {
//数组
private Object[] array;
//list
private List list;
//set
private Set set;
//map
private Map map;
//properties
private Properties prop;
public Object[] getArray() {
return array;
}
public void setArray(Object[] array) {
this.array = array;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProp() {
return prop;
}
public void setProp(Properties prop) {
this.prop = prop;
}
@Override
public String toString() {
return "MyCollection [list="+list+",set="+set+",map=" + map + ", prop=" + prop + "]";
}
}
xml代码片段如下:
<!-- 复杂类型注入 -->
<bean name="collection" class="com.sikiedu.bean.MyCollection">
<!-- array -->
<!-- 一个数据可以这样写 -->
<property name="array" value="123">
<!--多个数据可以这样写
<property name="array">
<array>
<value>123</value>
<value>abc</value>
<ref bean="dog"/>
</array> -->
</property>
<!-- list -->
<property name="list">
<list>
<value>456</value>
<value>cba</value>
<ref bean="user1"/>
</list>
</property>
<!--set -->
<property name="set">
<set>
<value>111</value>
<value>aaa</value>
<ref bean="user1"/>
</set>
</property>
<!-- map -->
<property name="map">
<map>
<entry key="username" value="root"/>
<entry key="password" value="123"/>
<entry key-ref="user1" value-ref="dog"/>
</map>
</property>
<!-- properties -->
<property name="prop">
<props>
<prop key="name">老李</prop>
<prop key="age">25</prop>
</props>
</property>
</bean>
网友评论