Spring中Bean的配置详解(基于XML)

配置bean
-配置形式:基于XML文件的配置;基于注解方式的配置
-Bean的配置方式:通过全类名(反射)、工厂方法、FactoryBean。本文将通过全类名的方式配置bean

1.通过XML文件中通过bean节点来配置bean
首先准备一个类,HelloWorld类,在com.aa包下

public class HelloWorld {
	public HelloWorld() {}
}

xml中配置bean,为HelloWorld的属性赋值初始化

<!--通过全类名的方式配置Bean-->
<bean id="helloWorld" class="com.aa.HelloWorld">
</bean>

id:Bean的名称,在IOC容器中必须是唯一的。如果id没有指定,Spring自动将权限定性类名作为Bean的名字。id可以指定多个名字,名字之间用逗号、分号、或空格分隔

2.Spring的属性注入
即通过setter方法注入Bean的属性值或依赖对象,属性注入使用property元素,使用name属性指定Bean的属性名称,value属性或子节点指定属性值
如,HelloWorld类中有一个name属性,添加name的setter方法

public class HelloWorld {
	private String name;
	public void setName(String name) {
		System.out.println("HelloWorldName:"+name);
		this.name = name;
	}
	}
	
}

xml中通过属性注入bean:

<!--com.aa.HelloWorld为HelloWorld的全类名-->
<bean id="helloWorld" class="com.aa.HelloWorld">
	<property name="name" value="aaaxxxx">
</bean>

3.构造方法注入
在con.aa包下准备一个car类,代码如下


public class Car {

	private String brand;
	private String fac;
	private double price;
	private int  maxSpeed;
	
	public Car(String brand,String fac,double price) {
		this.brand = brand;
		this.fac = fac;
		this.price = price;
	}
	
	public Car(String brand,String fac,int maxSpeed) {
		this.brand = brand;
		this.fac = fac;
		this.maxSpeed = maxSpeed;
	}

	@Override
	public String toString() {
		return "Car [brand=" + brand + ", fac=" + fac + ", price=" + price + ", maxSpeed=" + maxSpeed + "]";
	}
	
}

当构造方法没有重载时,可以按照索引匹配入参。

<bean id="car" class="com.aa.Car">
<constructor-arg value="布加迪威龙" index=0></constructor-arg>
<constructor-arg value="中国" index=1></constructor-arg>
<constructor-arg value="5000000" index=2></constructor-arg>
</bean>

当构造方法有重载时,无法根据索引为bean注入,初始化bean,则可以按照类型匹配入参

<!-- 根据构造器配置bean,根据不同的参数类型,匹配不同的构造方法-->
	<bean class="com.aa.Car" id="car1">
		<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
		<constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg>
		<constructor-arg type="int">
			<!-- 字面量赋值的另一种方式 -->
			<value>250</value>
		</constructor-arg>
	</bean>

4.引用其他Bean
组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能. 要使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用
在 Bean 的配置文件中, 可以通过 元素或 ref 属性为 Bean 的属性或构造器参数指定对 Bean 的引用.
也可以在属性或构造器里包含 Bean 的声明, 这样的 Bean 称为内部 Bean
在这里插入图片描述
示例代码:

public class Person {
	private String name;
	private int age;
	private Car car;
	
	public Person() {
		
	}
	public Person(String name, int age, Car car) {
		super();
		this.name = name;
		this.age = age;
		this.car = car;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Car getCar() {
		return car;
	}
	public void setCar(Car car) {
		this.car = car;
	}
	
	
}

如果不是用bean的引用为person中的car属性赋值时:

<bean id="person2" class="com.aa.Person">
		<property name="name" value="xiaoming"></property>
		<property name="age" value="20"></property>
		<property name="car">
			<bean class="com.aa.Car" >
				<constructor-arg value="aotr" type="java.lang.String"></constructor-arg>
				<constructor-arg value="Shanghai" type="java.lang.String"></constructor-arg>	
				<constructor-arg value="300000" type="double"></constructor-arg>		
			</bean>
		</property>
	</bean>

<!--使用bean引用-->
	<bean id="person2" class="com.ist.newBean.Person">
		<property name="name" value="xiaoming"></property>
		<property name="age" value="20"></property>
		<property name="car" ref="car">
		</property>
	</bean>

<!--使用构造器配置bean时,bean之间的引用-->
<bean id="person3" class="com.aa.Person">
		<constructor-arg value="xiaowang" type="java.lang.String"></constructor-arg>
		<constructor-arg value="22" type="int"></constructor-arg>
		<constructor-arg ref="car"></constructor-arg>
	</bean>

5.注入参数详解:注入null和级联属性
可以使用专用的 元素标签为 Bean 的字符串或其它对象类型的属性注入 null 值
和 Struts、Hiberante 等框架一样,Spring 支持级联属性的配置。

	<!-- 赋值null -->
	<bean id="person4" class="com.aa.Person">
		<constructor-arg value="xiaoming" ></constructor-arg>
		<constructor-arg value="22" ></constructor-arg>
		<constructor-arg><null/></constructor-arg>
	</bean>
	<!-- 测试级联 -->
	<bean id="person5" class="com.aa.Person">
		<constructor-arg value="xiaoming"></constructor-arg>
		<constructor-arg value="22"></constructor-arg>
		<constructor-arg>
			<bean class="com.aa.Car">
				<constructor-arg value="aodi"></constructor-arg>
				<constructor-arg value="shenzhen"></constructor-arg>
				<constructor-arg value="500000" type="double"></constructor-arg>
			</bean>
		</constructor-arg>
		<property name="car.maxSpeed" value="250"></property>
		
	</bean>

注意:级联属性时,bean属性必须先初始化,例如案例中Car属性如果没有初始化就级联属性则会保存。
6.集合属性
6.1首先准备一个类,里边有list集合属性

public class Person2 {
	private String name;
	private int age;
	private List<Car> cars;
	@Override
	public String toString() {
		return "Person2 [name=" + name + ", age=" + age + ", car=" + cars + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public List<Car> getCar() {
		return cars;
	}
	public void setCars(List<Car> car) {
		this.cars = car;
	}
	
}

xml中的配置

<!-- 测试给List集合赋值 ,使用list标签-->
	<bean id="person6" class="com.aa.Person2">
		<property name="name" value="huahua"></property>
		<property name="age" value="22"></property>
		<property name="cars">
			<list>
				<ref bean="car1"/>	<!--引用bean-->
				<ref bean="car2"/>  <!--引用bean-->
			</list>
		</property>
	</bean>

6.2首先准备一个类,里边有map集合属性

public class Person3 {
	private String name;
	private int age;
	private Map<String,Car> cars;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Map<String, Car> getCars() {
		return cars;
	}
	public void setCars(Map<String, Car> cars) {
		this.cars = cars;
	}
	@Override
	public String toString() {
		return "Person3 [name=" + name + ", age=" + age + ", cars=" + cars + "]";
	}
	
}

xml中bean的配置

	<!-- 测试给map集合赋值,使用map标签 -->
	<bean id="person7" class="com.aa.Person3">
		<property name="name" value="xiaoming"></property>
		<property name="age" value="25"></property>
		<property name="cars">
			<map>
				<entry key="aaa" value-ref="car1"></entry>
				<entry key="bbb" value-ref="car2"></entry>			
			</map>
		</property>
	</bean>

6.3:Propertirs属性的注入

public class Person4 {
	
	private String name;
	private int age;
	private Properties properties;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Properties getProperties() {
		return properties;
	}
	public void setProperties(Properties properties) {
		this.properties = properties;
	}
	@Override
	public String toString() {
		return "Person4 [name=" + name + ", age=" + age + ", properties=" + properties + "]";
	}
	
	
}

<bean id="person8" class="com.aa.Person4">
	<property name="name" value="lili"></property>
	<property name="age" value="55"></property>
	<property name="properties">
		<props>
			<prop key="user">root</prop>
			<prop key="password">paaa</prop>
			<prop key="jdbUrl">jdbc:mysql:///test</prop>
			<prop key="driverClass">com.mysql.jdbc.Driver</prop>
		</props>
	</property>
</bean>

xml中还可以配置单例的集合bean,供多个bean进行引用

<!-- 配置单例的集合bean,以供多个bean进行引用 -->
	<util:list id="cars">
		<ref bean="car1"/>
		<ref bean="car2"/>
		<bean class="com.aa.Car">
			<constructor-arg value="bujiadiwei"></constructor-arg>
			<constructor-arg value="china"></constructor-arg>
			<constructor-arg value="400" type="int"></constructor-arg>
		</bean>
	</util:list>
	<bean class="com.aa.Person2" id="person9">
		<property name="name" value="xihong"></property>
		<property name="age" value="40"></property>
		<property name="cars" ref="cars"></property>
	</bean>

7.使用p的命名空间
为了简化XML文件的配置,采用属性而非子元素配置信息。Spring从2.5版本开始引入了一个新的p命名空间,可以通过元素属性的方式配置Bean的属性
示例:准备一个类Address,其中有城市city属性和street街道属性,准备setter方法。在xml 中使用p命名空间为其属性赋值

	<bean id="address" class="Address的全类名" p:city="xinxiang" p:street="hongmen" ></bean>

8.自动装配
Spring IOC 容器可以自动装配 Bean. 需要做的仅仅是在 的 autowire 属性里指定自动装配的模式
byType(根据类型自动装配): 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这种情况下, Spring 将无法判定哪个 Bean 最合适该属性, 所以不能执行自动装配.
byName(根据名称自动装配): 必须将目标 Bean 的名称和属性名设置的完全相同.
constructor(通过构造器自动装配): 当 Bean 中存在多个构造器时, 此种自动装配方式将会很复杂. 不推荐使用

XML配置里的Bean自动装配的缺点
在 Bean 配置文件里设置 autowire 属性进行自动装配将会装配 Bean 的所有属性. 然而, 若只希望装配个别属性时, autowire 属性就不够灵活了.autowire 属性要么根据类型自动装配, 要么根据名称自动装配, 不能两者兼而有之.
一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些
示例代码:首先在com.auto包下准备三个类


public class Address {
	private String city;
	private String street;
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	@Override
	public String toString() {
		return "Address [city=" + city + ", street=" + street + "]";
	}
	
}

public class Car {
	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;
	}
	@Override
	public String toString() {
		return "Car [name=" + name + ", price=" + price + "]";
	}
	
	public Car() {
		
	}
}
public class Person {
	private String name;
	private Address address;
	private Car car;
	@Override
	public String toString() {
		return "Person [name=" + name + ", address=" + address + ", car=" + car + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public Car getCar() {
		return car;
	}
	public void setCar(Car car) {
		this.car = car;
	}
	
}

xml配置:

	<bean id="address" class="com.auto.Address" p:city="xinxiang" p:street="hongmen" ></bean>
	
	<bean id="car" class="com.auto.Car" p:name="audi" p:price="300000" ></bean>
	
	<!-- 自动装配,可以选择两种方式:byType和byName -->
	<!-- byName方式 -->
 	<bean id="person" class="com.auto.Person" p:name="xiaoming" autowire="byName"></bean> 
	<!-- byType方式 ,不能出现一个以上能够匹配的同一个bean类型的,即不能出现两个car的bean-->
	<!-- <bean id="person" class="com.auto.Person" p:name="honghuazhen" autowire="byType"></bean> -->

9.Bean的继承
1.Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean
2.子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置
3.子 Bean 也可以覆盖从父 Bean 继承过来的配置
4.父 Bean 可以作为配置模板, 也可以作为 Bean 实例. 若只想把父 Bean 作为模板, 可以设置 的abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean
5.并不是 元素里的所有属性都会被继承. 比如: autowire, abstract 等.
6.也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置. 但此时 abstract 必须设为 true

<!--
<bean id="address2" class="com.auto.Address" p:city="xinxiang" p:street="hongmen" ></bean>
-->
<bean id="address2" class="com.auto.Address" p:city="xinxiang" p:street="hongmen" abstract="true"></bean>
<bean id="address3"   parent="address2"></bean>

上述两个address2bean均可被继承,唯一的不同是带有abstract属性的bean不会初始化,只是作为模板
另一种继承的配置:

	<bean id="address2" p:city="xinxiang" p:street="hongmen" abstract="true"></bean>
	<bean id="address3" class="com.auto.Address" p:city="beijing" parent="address2"></bean><!-- 覆盖父bean中的city属性 -->

10:依赖Bean的配置
Spring 允许用户通过 depends-on 属性设定 Bean 前置依赖的Bean,前置依赖的 Bean 会在本 Bean 实例化之前创建好
如果前置依赖于多个 Bean,则可以通过逗号,空格或的方式配置 Bean 的名称
配置如下:

<!--没有依赖的情况下 -->
	<bean id="person2" class="com.auto.Person" p:name="hongmenzhen" p:address-ref="address3"></bean>

	<!-- 添加bean的依赖,添加后如果没有依赖的bean,则会抛出异常 -->
	<bean id="person3" class="com.auto.Person" p:name="开玩笑" p:address-ref="address3" p:car-ref="car" depends-on=""></bean>
	```
11.Bean的作用域
在 Spring 中, 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域. 
默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190930191404515.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjg3OTkw,size_16,color_FFFFFF,t_70)
示例:

<bean id="car" class="com.auto.Car" p:name="audi" p:price="300000" scope="prototype"></bean>
12.使用外部属性文件
在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离
Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量.
Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用。

<!--不使用外部资源-->
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="user" value="root"></property>
	<property name="password" value="admin"></property>
	<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
	<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
</bean>
<!--使用外部资源-->
 <context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverclass}"></property>
<property name="jdbcUrl" value="${jdbcurl}"></property>
</bean> 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值