Spring配置Bean有两种形式(XML和注解)
本文演示通过XML方式配置Bean
演示案例工程的目录结构:
1、 Bean的配置方式
通过全类名(反射)的方式
id:标识容器中的bean。id唯一。
class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有无参的构造器
2、依赖注入的方式
1)属性注入:通过setter方法注入Bean的属性值或依赖的对象
属性注入使用<Property>元素,使用name指定Bean的属性名称,使用value指定Bean的属性的值
2)构造器注入:通过构造方法注入Bean的属性和值
首先创建一个Car类
package com.dk.spring.beans;
public class Car {
private String brand;
private int speed;
private String color;
public int price;
public Car(String brand, int speed, String color,int price) {
System.out.println("Car...初始化有参构造器");
this.brand = brand;
this.speed = speed;
this.color = color;
this.price = price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", speed=" + speed + ", color=" + color + ", price=" + price + "]";
}
}
然后加入配置文件配置节点: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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi"></constructor-arg>
<constructor-arg value="120"></constructor-arg>
<constructor-arg value="black"></constructor-arg>
<constructor-arg value="1000"></constructor-arg>
</bean>
</beans>
编写测试类SpringBeanConfig.java
运行main方法开启Spring容器并使用
package com.dk.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dk.spring.beans.Address;
import com.dk.spring.beans.Car;
import com.dk.spring.beans.OtherPerson;
import com.dk.spring.beans.Person;
import com.dk.spring.beans.RichPerson;
public class SpringBeanConfig {
public static void main(String[] args) {
// 1.创建Spring 的IOC的容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.从IOC容器中获取bean实例
Car car = (Car)ctx.getBean(Car.class);
// 3、调用hello方法
System.out.println(car);
}
}
如果想给指定属性顺序赋值,可以使用index属性
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" index="0"></constructor-arg>
<constructor-arg value="120" index="1"></constructor-arg>
<constructor-arg value="black" index="2"></constructor-arg>
<constructor-arg value="1000" index="3"></constructor-arg>
</bean>
</beans>
如果想给指定属性顺序赋值,也可以使用type属性
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" type="int"></constructor-arg>
</bean>
</beans>
备注:改变参数配置顺序,会影响赋值顺序,【赋值会根据同一类型出现的顺序依次赋值】,如下图所示
所以这种方式注入的话要注意赋值类型顺序。
3)工厂方法注入
静态工厂方法注入bean
利用静态工厂方法可以把bean注入到IOC容器中。在XML文件中配置bean时,要指定class的属性为工厂的类;factory-method属性指定工厂类中工厂方法,用于创建bean;constrctor-arg用于给工厂方法传递参数。实例如下:
ExampleBean.java
package com.dk.spring.beans;
public class ExampleBean {
private String name;
public ExampleBean() {
System.out.println("ExamleBean的无参构造器...");
}
public ExampleBean(String name) {
System.out.println("ExamleBean的有参构造器...");
this.name = name;
}
public static ExampleBean getInstance(String name){
return new ExampleBean(name);
}
@Override
public String toString() {
return "ExampleBean [name=" + name + "]";
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<!--class要写工厂的类;factory-method要写工厂类中用于创建bean的方法-->
<!--
使用静态工厂方法创建一个对象
factory-method属性:指定要调用的静态方法。
-->
<bean id="exampleBean" class="com.dk.spring.beans.ExampleBean"
factory-method="getInstance">
<constructor-arg value="Jack"></constructor-arg>
</bean>
</beans>
实例工厂方法注入bean
实例化工厂方法注入bean,需要先实例化一个工厂类,然后通过由实例化工厂对象中的一个方法来创建bean,并注入到容器中。
在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean;在 factory-method 属性里指定该工厂方法的名称;使用 construtor-arg 元素为工厂方法传递方法参数。示例如下
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<!-- 使用静态工厂方法创建一个对象 factory-method属性:指定要调用的静态方法。 -->
<!--class要写工厂的类;factory-method要写工厂类中用于创建bean的方法 -->
<bean id="exampleBean" class="com.dk.spring.beans.ExampleBean"
factory-method="getInstance">
<constructor-arg value="Jack"></constructor-arg>
</bean>
<!-- 使用实例工厂方法创建一个对象 factory-bean属性:要调用的对象的id。 factory-method属性:要调用的方法。 -->
<bean id="calendar" class="java.util.GregorianCalendar" />
<bean id="time" factory-bean="calendar" factory-method="getTime" />
<bean id="carFactory" class="com.dk.spring.beans.CarFactory"></bean>
<bean id="car" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="baoma"></constructor-arg>
<constructor-arg value="102"></constructor-arg>
<constructor-arg value="baoma"></constructor-arg>
<constructor-arg value="100000"></constructor-arg>
</bean>
</beans>
CarFactory.java
package com.dk.spring.beans;
public class CarFactory {
public Car getCar(String brand, int speed, String color,int price){
return new Car(brand, speed, color, price);
}
}
配置bean的属性时可以 使用ref引用其他配置好的bean对象,ref的值为引用bean的id
构造器方式<constructor-arg ref="car"></constructor-arg>
属性注入<property name="name" ref=""></property>
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="helloworld" class="com.dk.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<!-- 使用静态工厂方法创建一个对象 factory-method属性:指定要调用的静态方法。 -->
<!--class要写工厂的类;factory-method要写工厂类中用于创建bean的方法 -->
<bean id="exampleBean" class="com.dk.spring.beans.ExampleBean"
factory-method="getInstance2">
<constructor-arg ref="car"></constructor-arg>
</bean>
<!-- 使用实例工厂方法创建一个对象 factory-bean属性:要调用的对象的id。 factory-method属性:要调用的方法。 -->
<bean id="calendar" class="java.util.GregorianCalendar" />
<bean id="time" factory-bean="calendar" factory-method="getTime" />
<bean id="carFactory" class="com.dk.spring.beans.CarFactory"></bean>
<bean id="car" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="baoma"></constructor-arg>
<constructor-arg value="102"></constructor-arg>
<constructor-arg value="baoma"></constructor-arg>
<constructor-arg value="100000"></constructor-arg>
</bean>
</beans>
package com.dk.spring.beans;
public class ExampleBean {
private String name;
private Car car;
public ExampleBean(Car car) {
System.out.println("ExamleBean的有参构造器...");
this.car = car;
}
public static ExampleBean getInstance2(Car car){
return new ExampleBean(car);
}
public ExampleBean() {
System.out.println("ExamleBean的无参构造器...");
}
public ExampleBean(String name) {
System.out.println("ExamleBean的有参构造器...");
this.name = name;
}
public static ExampleBean getInstance(String name){
return new ExampleBean(name);
}
@Override
public String toString() {
return "ExampleBean [name=" + name + ", car=" + car + "]";
}
}
工厂方法方式在实际的项目中很少使用,使用最多的是属性注入、构造器注入。
3、引用其他Bean
1)引用外部Bean
使用 property的ref属性建立Bean之间的引用关系
package com.dk.spring.beans;
public class Person {
private String name;
private int age;
private 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;
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100000"></constructor-arg>
</bean>
<bean id="person" class="com.dk.spring.beans.Person">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<!-- 使用 property的ref属性建立Bean之间的引用关系-->
<property name="car" ref="car"></property>
</bean>
</beans>
2)引用内部Bean
因为id是为了让外部引用,而内部Bean内部只用一次,不能被外部引用,所以不写id。
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="person" class="com.dk.spring.beans.Person">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<!-- 内部Bean,不能被外部引用,只能在内部使用 -->
<property name="car">
<bean class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100000"></constructor-arg>
</bean>
</property>
</bean>
</beans>
4、级联属性
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="person" class="com.dk.spring.beans.Person">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<property name="car" ref="car"></property>
<!-- 级联属性赋值 -->
<property name="car.price" value="30000"></property>
</bean>
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" index="0"></constructor-arg>
<constructor-arg value="120" index="1"></constructor-arg>
<constructor-arg value="black" index="2"></constructor-arg>
<constructor-arg value="1000" index="3"></constructor-arg>
</bean>
</beans>
注意:属性想用car.price的级联,首先car必须要先初始化,否则会有异常
4、集合属性
当我们的Bean中有集合元素的时候,Spring中可以通过一组内置的xml标签(<list>、<set>、<map>)来配置集合属性。
1)List集合:
创建RichPerson类有一个cars属性,并且RichPerson类cars属性是一个List<car>,即一个人拥有多辆车。
package com.dk.spring.beans;
import java.util.List;
import java.util.Map;
public class RichPerson {
private String name;
private int age;
private List<Car> cars;
private Map<String,Car> cars2;
//为上面的4个属性设置getter和setter方法
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> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public Map<String,Car> getCars2() {
return cars2;
}
public void setCars2(Map<String,Car> cars2) {
this.cars2 = cars2;
}
}
配置文件修改如下:
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car1" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" type="int"></constructor-arg>
</bean>
<bean id="car2" class="com.dk.spring.beans.Car">
<constructor-arg value="Ford" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" index="3"></constructor-arg>
</bean>
<bean id="car3" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" type="int"></constructor-arg>
</bean>
<bean id="richPerson" class="com.dk.spring.beans.RichPerson">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<!-- 集合属性(List),使用ref来配置子节点信息 -->
<property name="cars">
<list>
<ref bean="car1"></ref>
<ref bean="car2"></ref>
<ref bean="car3"></ref>
</list>
</property>
</bean>
</beans>
2)Map集合:
如果是<map>集合的话,只需要把list换成map即可。
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car1" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" type="int"></constructor-arg>
</bean>
<bean id="car2" class="com.dk.spring.beans.Car">
<constructor-arg value="Ford" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" index="3"></constructor-arg>
</bean>
<bean id="car3" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="1000" type="int"></constructor-arg>
</bean>
<bean id="richPerson" class="com.dk.spring.beans.RichPerson">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<!-- 集合属性(List),使用ref来配置子节点信息 -->
<property name="cars">
<list>
<ref bean="car1"></ref>
<ref bean="car2"></ref>
<ref bean="car3"></ref>
</list>
</property>
<!-- 集合属性(Map),使用entry来配置map的子节点信息 -->
<property name="cars2">
<map>
<entry key="A" value-ref="car1"></entry>
<entry key="B" value-ref="car2"></entry>
</map>
</property>
</bean>
</beans>
3) 现在这么多集合Bean能不能抽出来,以供多个Bean进行引用,那么就需要使用util
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car1" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car2" class="com.dk.spring.beans.Car">
<constructor-arg value="Ford" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car3" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="richPerson" class="com.dk.spring.beans.RichPerson">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
<!-- 引用util -->
<property name="cars" ref="cars"></property>
</bean>
<util:list id="cars">
<ref bean="car1"></ref>
<ref bean="car2"></ref>
</util:list>
</beans>
4)使用p命名空间
Sping从2.5版本开始引入一个新的P的命名空间,通过使用P命名空间后,使得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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car1" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car2" class="com.dk.spring.beans.Car">
<constructor-arg value="Ford" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car3" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<util:list id="cars">
<ref bean="car1"></ref>
<ref bean="car2"></ref>
</util:list>
<!-- 通过P命名空间为Bean属性赋值,相对于传统的配置方式更加简洁 -->
<bean id="richPerson" class="com.dk.spring.beans.RichPerson" p:name="dk"
p:age="25" p:cars-ref="cars">
</bean>
</beans>
通过C名称空间来简化我们构造方法的属性赋值
package com.dk.spring.beans;
import java.util.List;
import java.util.Map;
public class RichPerson {
private String name;
private int age;
private List<Car> cars;
private Map<String,Car> cars2;
//构造函数(C命名空间使用)
public RichPerson(String name, int age, List<Car> cars) {
System.out.println("RichPerson有参构造器初始化。。。。");
this.name = name;
this.age = age;
this.cars = cars;
}
//为上面的4个属性设置getter和setter方法
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> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public Map<String,Car> getCars2() {
return cars2;
}
public void setCars2(Map<String,Car> cars2) {
this.cars2 = cars2;
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car1" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
<constructor-arg value="120" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car2" class="com.dk.spring.beans.Car">
<constructor-arg value="Ford" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="car3" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<util:list id="cars">
<ref bean="car1"></ref>
<ref bean="car2"></ref>
</util:list>
<!-- 通过C名称空间来简化我们构造方法的属性赋值 -->
<bean id="richPerson" class="com.dk.spring.beans.RichPerson" c:name="dk"
c:age="25" c:cars-ref="cars">
</bean>
</beans>
5、使用autowire属性进行Bean的自动装配
当我们要往一个bean的某个属性里注入另外一个bean,我们会使用<property ref=“”>标签的形式。但是对于大型项目这种方式其实是不可取的。
package com.dk.spring.beans;
public class Person {
private String name;
private int age;
private 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;
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!-- 使用autowire属性进行Bean的自动装配 -->
<!--
大型项目中我们一般使用autowire属性自动装备Bean,autowire属性有两个值:byName和byType
byName:根据Bean的名字和当前的Bean的setter属性名称进行装配 若没有,则为null
byType:根据Bean的类型进行装配,若有1个以上的同一类型,则抛异常
-->
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Toyota" type="java.lang.String"></constructor-arg>
<constructor-arg value="95" type="int"></constructor-arg>
<constructor-arg value="black" type="java.lang.String"></constructor-arg>
<constructor-arg value="100" type="int"></constructor-arg>
</bean>
<bean id="person" class="com.dk.spring.beans.Person" autowire="byName">
<property name="name" value="dk"></property>
<property name="age" value="32"></property>
</bean>
</beans>
自动装配的特点:
1)只有引用类型才可以自动装配。
2)autowire属性是在bean的级别上,一旦指定,当前bean的所有引用类型都必须使用自动装配。
3)byType和byName的只能选择其一。
byType:异常情况演示
byName:
异常情况演示:
6、配置上的继承(parent属性)
当我们有两个或者以上的同一个类型的Bean做实例化的时候,我们可以将一些公共的部分提取成通用Bean。这样其他的Bean继承它即可以了。
package com.dk.spring.beans;
public class Address {
private String provice;
private String city;
private String street;
public String getProvice() {
return provice;
}
public void setProvice(String provice) {
this.provice = provice;
}
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 [provice=" + provice + ", city=" + city + ", street=" + street + "]";
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="address1" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YingBing">
</bean>
<bean id="address2" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YanLing">
</bean>
<bean id="address3" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YanShun">
</bean>
</beans>
以上Bean中用的都是address这个类,都是省市街道的赋值,只是在街道上每个不一样,所以我们完全可以把通用的提出来。
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!--
<bean id="address1" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YingBing">
</bean>
<bean id="address2" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YanLing">
</bean>
<bean id="address3" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YanShun">
</bean>
-->
<bean id="address" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YingBing" scope="prototype">
</bean>
<bean id="address1" parent="address" p:street="YanLing">
</bean>
<bean id="address2" parent="address" p:street="YanShun">
</bean>
</beans>
7、Bean的作用域(scope属性)
输出结果为:true
说明默认为单例模式的,主要看scope属性值。
使用Bean的scope属性来配置Bean的作用域的,scope有两个重要的属性值。
singleton:默认值,容器初始化时创建Bean实例,在整个容器的生命周期内只创建一个Bean,单例的。
prototype:原型的,容器初始化时不创建Bean的实例,而在每次请求时都创建一个新的Bean的实例,并返回。
8、使用外部属性文件(property-placeholder 属性占位符)
新建一个db.properties文件
user=root
password=1234
driverClass=com.mysql.jdbc
jdbcUrl=jdbc:mysql:///test
MyDataSource文件:
package com.dk.spring;
public class MyDataSource {
private String user;
private String password;
private String diverClass;
private String jdbcUrl;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDiverClass() {
return diverClass;
}
public void setDiverClass(String diverClass) {
this.diverClass = diverClass;
}
public String getJdbcUrl() {
return jdbcUrl;
}
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
@Override
public String toString() {
return "MyDataSource{" +
"user='" + user + '\'' +
", password='" + password + '\'' +
", diverClass='" + diverClass + '\'' +
", jdbcUrl='" + jdbcUrl + '\'' +
'}';
}
}
配置上属性占位符是文件的地址,并在使用的过程中使用${}的格式取值
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!-- 导入属性文件 -->
<context:property-placeholder location="db.properties"></context:property-placeholder>
<bean id="dataSource" class="com.dk.spring.MyDataSource">
<!-- 使用外部属性文件的属性值 -->
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="diverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
</bean>
</beans>
9、Spring表达式SPEL表达式
package com.dk.spring.beans;
public class OtherPerson {
private Car car;
private String city;
private String info;
private int yaowei;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public int getYaowei() {
return yaowei;
}
public void setYaowei(int yaowei) {
this.yaowei = yaowei;
}
@Override
public String toString() {
return "OtherPerson [car=" + car + ", city=" + city + ", info=" + info + ", yaowei=" + yaowei + "]";
}
}
<?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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car" class="com.dk.spring.beans.Car">
<constructor-arg value="Audi" index="0"></constructor-arg>
<constructor-arg value="120" index="1"></constructor-arg>
<constructor-arg value="black" index="2"></constructor-arg>
<constructor-arg value="1000" index="3"></constructor-arg>
</bean>
<bean id="address" class="com.dk.spring.beans.Address" p:provice="Hebei"
p:city="LangFang" p:street="YingBing">
</bean>
<!-- Spring表达式SPEL表达式 -->
<bean id="otherPerson" class="com.dk.spring.beans.OtherPerson">
<!-- 使用SpEL 来应用其他的Bean -->
<property name="car" value="#{car}"></property>
<!-- 使用SpEL 来应用其他的Bean的属性 -->
<property name="city" value="#{address.city}"></property>
<!-- 使用SpEL 中使用运算符 -->
<property name="info" value="#{car.price > 30000 ? '金领' : '白领'}"></property>
<!-- 使用SpEL 引用类的静态属性 -->
<property name="yaowei" value="#{T(java.lang.Math).PI * 80}"></property>
</bean>
</beans>
10、Spring中Bean的生命周期
1)创建Bean的实例
2)为Bean的属性设置值和对其他Bean的引用
3)Bean后置处理器postProcessBeforeInitialization方法
4)调用Bean的初始化方法(init-method)
5)Bean后置处理器的postProcessAfterInitialization方法
6)Bean正常使用
7)当容器关闭时,调用Bean的销毁方法(destroy-method)
实例:
package com.dk.spring.life;
public class Car {
public Car() {
System.out.println("构造器……");
}
private String brand;
public void setBrand(String brand) {
System.out.println("设置属性……");
this.brand = brand;
}
public void init(){
System.out.println("初始化……");
}
public void destroy(){
System.out.println("销毁……");
}
}
MyBeanProcessor必须实现BeanPostProcessor接口的两个方法:
package com.dk.spring.life;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization……");
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization……");
return o;
}
}
配置文件:
<?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"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="car" class="com.dk.spring.life.Car" p:brand="Audi" init-method="init"
destroy-method="destroy"></bean>
<!-- 配置Bean的处理器 -->
<bean class="com.dk.spring.life.MyBeanProcessor"></bean>
</beans>
测试类:
package com.dk.spring.life;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeTest {
public static void main(String[] args) {
// 由于ApplicationContext没有close方法,所以要使用它下面子接口ConfigurableApplicationContext
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-beanLife.xml");
Car car = (Car) ctx.getBean("car");
System.out.println("使用Bean:" + car.toString());
// 关闭IOC容器
ctx.close();
}
}
最终运行结果验证了上面的spring中bean的生命周期: