文章目录
1 Beans概述
每一个对象在xml中的映射对应一个元素,多个bean组成benas
-
description
指定一些描述信息,通常可以省略。 -
import
通过此元素对其所依赖的配置文件进行引用,A.xml中定义可能依赖B.xml中的某些定义,就可以在A.xml中使用将其引入 -
alias
为bean起别名。
其中beans拥有相应的属性用于对所管理的bean进行统一默认行为配置
-
default-lazy-init
其值可以指定为true或false,用来标识是否对所有的bean进行延迟初始化 -
default-autowire
用来标志bean使用的哪一种绑定方式:no,byName,byType -
default-init-method=“init”
统一指定方法名相同方法的初始化方法 -
default-destroy-method=“destory”
统一指定方法名相同方法销毁方法
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="no"
default-lazy-init="false"
default-init-method="init"
default-destroy-method="destory"
>
<context:component-scan base-package="org.example"/>
<!--引入B.xml-->
<import resource="B.xml"></import>
<!--为bean起别名-->
<alias name="person" alias="per"></alias>
<!--注册到的对象-->
<bean id="person" class="org.example.Person">
</bean>
</beans>
2 Bean 概述
最基础的对象配置方式
<bean id="person" class="org.example.Person">
</bean>
-
id 属性
用于在容器中唯一标志出注册对象 -
class 属性
为容器中的对象指定其所属的类型。
2.1 Bean构造注入方式
2.1.1 构造方法注入
通过构造方法注入需要使用<constructor-arg>
通过<ref>
指向依赖对象
<bean id="per1" class="org.example.Person1">
<constructor-arg>
<ref bean ="dog"></ref>
</constructor-arg>
<!-- 简化版
<constructor-arg ref="dog"/>
-->
</bean>
<bean id="dog" class="org.example.Dog">
</bean>
-
type属性
可以通过type属性指定参数类型,默认是string类型 -
index 属性
当构造方法中传入了多个类型相同的参数,可以使用index进行对应。
2.1.2 setter方式的注入
spring为setter方法注入提供了<property>
元素
<bean id ="per" class="org.example.Person">
<!--引用类型使用ref-->
<property name="dog" ref="dog"/>
<!--属性的setter注入使用value-->
<property name="name" value="wfg"/>
</bean>
如果是使用setter方法注入的话,需要对象提供默认的构造器(无参数)
2.2 property和constructor-arg常用配置项
包括 bean,ref,idref,value,null,list,set,map
2.2.1 value
通过value向对向注入简单的数据类型
2.2.2 ref
使用ref来引用容器中其他对象实例,其中包括三种对应属性,local,parent.bean
- local
只能指定与当前配置对象在同一配置文件的对象的定义 - parent
指定位于当前容器的父容器定义的对象引用 - bean
通吃,基本上使用bean指定对象引用
2.2.3 内部bean
使用ref可以引用容器中独立定义的对象定义,但是当我们不想让其他对象通过引用时,可以使用**将这个私有对象局限在当前对象**
2.2.4 list
对应注入对象类型为java.util.list及其子类或者数组的依赖对象。
<property name="list" >
<list>
<value>qwe</value>
<value>rty</value>
</list>
</property>
2.2.5 set
对应注入对象类型为java.util.set及其子类或者数组的依赖对象。
<property name="set" >
<list>
<value>qwe</value>
<value>rty</value>
</list>
</property>
2.2.6 map
对于map,它内部可以嵌套任意个,每个需要为其指定相应的key和value
-
指定entry的key
可以使用的属性key
和key-ref
来指定建,也可以使用内嵌元素 -
指定entry的值
里面可以使用上面元素指定,如果对应的值是原始类型或者单一的对象引用,也可以直接使用value或value-ref的属性进行指定
<property name="map">
<map >
<entry key="name">
<value>wfg</value>
</entry>
</map>
</property>
2.2.7 props
是简化的map,对应java.util.properties,只能指定string类型的键和值,每个可以嵌套多个 但是里面只能指定字符串。
<property name="properties">
<props>
<prop key="age">18</prop>
</props>
</property>
2.2.9
空元素,作用是当我们使用value为string赋值时得到的结果为"",而不是null,要为null则需要
2.3 autowire属性
通过autowire属性指定当前bean定义采用某种类型的自动绑定方式。
-
no
容器默认的绑定方式,不采用任何绑定方式,完全依赖手工明确配置各个bean之间的关系 -
byname
按照类中声明变量的名称,与xml配置文件中声明的bean定义的beanName的值进行匹配,并被自动绑定到当前实例上。
<!-- 将dog注入到per2中,无需显示的指定,通过byname可以直接引用
但条件是person中Dog的变量名与dog的beanName相等-->
<bean id = "per2" class="org.example.Person2" autowire="byName">
</bean>
<bean id="dog" class="org.example.Dog">
</bean>
- byType
分析其依赖类型,然后到容器锁管理的bean定义中寻找与依赖对象类型相同的bean定义,并进行绑定
这种只适用于一个符合条件的依赖对象,如果多个的话会报错
<bean id = "per2" class="org.example.Person2" autowire="byType">
</bean>
<bean id="anyName" class="org.example.Dog">
</bean>
-
constructor
byName和byType类型的自动绑定是针对property(setter方法注入)的,而constructor是针对构造方法参数类型进行的绑定,与byType类似 -
autodetect
是byType和constructor模式的结合体,有默认构造方法则会使用byType,否则使用constructor模式。
自动绑定的全局配置
中有个default-autowire属性可以为所有bean进行统一配置
自动绑定的优缺点
- 优点:减少配置量
- 缺点:bytype如果在类中新增了相同类型的则会崩溃,byname如果修改了变量名,也会崩溃
2.4 parent属性
相当于’继承’,通过parent会继承父bena的默认值,可以将特定的属性进行修改,通常会和abstract属性结合使用
,达到相应的bean定义模板化的目的
<bean id="perTemplate" abstract="true">
<property name="dog" ref="dog"/>
</bean>
<bean id = "per2" class="org.example.Person2" parent="perTemplate">
.....
</bean>
<bean id = "per1" class="org.example.Person1" parent="perTemplate">
.....
</bean>
2.5 scope属性
beanfactory除了拥有ioc service provider职责,还具有其他职责如:对象的生命周期管理。
其提供了两种scope类型:singleton和prototype进行管理,此外又在web应用中(applicationContext)引入了 request,session,global session.
2.5.1 singleton
配置中的bean定义可以看作为一个模板,容器会根据此进项创建对象,但是要构造出多少对象实例,又要让这些构造完的对象实例存活多久,则由scope进行决定。
-
对象的实例数量
singleton类型的bean定义,在一个容器中只存在一个共享实例 -
对象的存活时间
从容器中启动,直到它第一次被请求而实例化开始,只要容器不销毁或者退出,该类型bean的单一实例则会一直存活
2.5.2 prototype
容器在接受到该类型对象请求时,会重新生成一个新的对象实例给请求方,虽然这中类型的对象的实例化以及属性设置都是由容器负责的,但是请求方需要自己负责当前返回对象的后继生命周期的管理工作,包括对象的销毁
2.5.3 request
spring 容器,即xmlwebapplicationContext会为每个http请求创建一个全新的对象用于使用,当请求结束时,改对象的生命周期即结束。
2.5.4 session
为每个独立的session创建属于他们自己全新的对象实例
2.5.5 global session
只有应用在基于portlet的web应用程序才有意义。
2.6 工厂方法注入
当我们使用第三方库时,并且实例化第三方库中的相关类时,通常的做法是通过使用工厂方法模式,来提供一个工厂类来实例化具体的接口实现类。
2.6.1 静态方法工厂类
工厂类
public class PhoneFactory {
public static HuaWei getHuaWei(String name){
return new HuaWei(name);
}
public XiaoMi getXiaoMi(){
return new XiaoMi();
}
}
依赖由静态工厂创造的对象
<bean id ="pho" class="org.example.Day01.Phone">
<property name="huaWei" ref="huawei"/>
</bean>
<!--静态工厂创造对象-->
<bean id ="huawei" class="org.example.Day01.PhoneFactory" factory-method="getHuaWei"/>
<!--静态工厂方法带参数创造对象-->
<bean id ="huawei" class="org.example.Day01.PhoneFactory" factory-method="getHuaWei">
<constructor-arg value="wfg"/>
</bean>
class指向静态方法工厂类,factory-method指定工厂方法名称,然后容器调用该静态方法工厂类的指定方法,并返回调用后的结果。而constructor-arg为工厂方法传入相应的参数
2.6.2 非静态方法构造对象
<!--非静态方法构造对象-->
<bean id ="phoFac" class="org.example.Day01.PhoneFactory"></bean>
<bean id ="xiaomi" factory-bean="phoFac" factory-method="getXiaoMi"/>
使用factory-bean属性
指定工厂方法所在的工厂类实例。
2.6.3 factoryBean
factory bean 本身与其他注册到容器的对象一样,只是个bean,这种类型的bean本身就是生产对象的工厂,当第三方不能直接注册到spring容器中时,就可以实现factorybean接口。
public class AnimalFac implements FactoryBean {
@Override
public Object getObject() throws Exception {
return null;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
实现factory bean 需要实现getObject,getObjectType,isSingleton
方法
- getObject
会返回factorybean生产的对象实例,我们常用实现该方法以给出自己的对象实例化逻辑 - getObjectType
会返回getObject方法所返回的对象类型 - isSingleton
表示所生产的对象是否要以singleton的形式存在
实现factorybean的工厂
public class AnimalFac implements FactoryBean {
private String name;
@Override
public Object getObject() throws Exception {
if(name.equals("cat"))
{return new Cat();}
else{
return null;
}
}
@Override
public Class<?> getObjectType() {
return Animal.class;
}
@Override
public boolean isSingleton() {
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
xml配置直接获取cat对象
<bean id="cat" class="org.example.Day01.AnimalFac">
<property name="name" value="cat"/>
</bean>
通过正常的id引用,容器会返回factorybean所生产的对象,而通过在bean定义的bean的id前面加上前缀&即可返回工厂。
//返回工厂生产对象
Animal cat =(Cat) ctx.getBean("cat");
System.out.println("cat:"+cat);
//返回工厂本身
AnimalFac af = (AnimalFac) ctx.getBean("&cat");
System.out.println("af:"+af);
2.7 方法注入
方法注入达到每次调用都让容器返回新的对象实例,其中该方法必须能够被子类实现或者覆写(public prodected),因为容器会为我们要进行方法注入的对象使用cglib生成子类实现代替对象。
java
public class Moive {
private People people;
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
}
xml中的配置
<bean id="mo" class="org.example.Day01.Moive">
<lookup-method name="getPeople" bean="per2"/>
</bean>
<bean id = "per2" class="org.example.Day01.People" scope="prototype">
</bean>
通过lookup-method的name属性指定要注入的方法名,bean属性指定要注入的对象当getPeople方法调用时,容器可以每次返回一个新的类型实例。
Moive moive =(Moive) ctx.getBean("mo");
System.out.println(moive.getPeople());
System.out.println(moive.getPeople());
//结果
org.example.Day01.People@710636b0
org.example.Day01.People@3de8f619