一、Spring自动装配介绍:
当spring装配bean属性时,有时候非常明确就是需要将某个bean注入到其他bean的property中。但spring框架默认是不支持自动装配的,为了应对这种明确的装备场景,Spring提供显示的装配 Bean属性方法(在spring的配置文件的<bean>标签中使用autowire属性来进行声明自动装配)。
spring目前提供了3类显示自动装配和1类默认装配(手动装配)策略
public interface AutowireCapableBeanFactory{
//无需自动装配
int AUTOWIRE_NO = 0;
//按名称自动装配bean属性
int AUTOWIRE_BY_NAME = 1;
//按类型自动装配bean属性
int AUTOWIRE_BY_TYPE = 2;
//按构造器自动装配
int AUTOWIRE_CONSTRUCTOR = 3;
//过时方法,Spring3.0之后不再支持
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
}
二、Spring装配方式具体使用方法:
首先我们先定义三个类(表达某人在某个地方从事某项工作,待遇如何):Person、Address、Work,生成get、set并重写toString()方法:
如:Person类:
package com.monkey.yb.autowire;
public class Person {
private String name;
private int age;
private Address address;
private Work work;
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 Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Work getWork() {
return work;
}
public void setWork(Work work) {
this.work = work;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", work=" + work +
'}';
}
}
Address类:
package com.monkey.yb.autowire;
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 + '\'' +
'}';
}
}
Work类:
package com.monkey.yb.autowire;
public class Work {
private String category;
private double salary;
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Work{" +
"category='" + category + '\'' +
", salary=" + salary +
'}';
}
}
1、默认方式:no
默认情况下都是使用该模式,使用该模式不会自动装配,需要通过ref来手动指定装配的bean
例如:在src目录下新建autowire.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="work" class="com.monkey.yb.autowire.Work">
<property name="category" value="it"></property>
<property name="salary" value="20000"></property>
</bean>
<bean id="address" class="com.monkey.yb.autowire.Address">
<property name="city" value="杭州"></property>
<property name="street" value="西湖区"></property>
</bean>
<!--未设定autowire参数,表示默认情况下不自动装配,通过ref手动装配-->
<bean id="person" class="com.monkey.yb.autowire.Person">
<property name="name" value="tomas"></property>
<property name="age" value="25"></property>
<property name="work" ref="work"></property>
<property name="address" ref="address"></property>
</bean>
</beans>
在上面配置文件中,person 这个bean中使用ref指定了work和address两个bean,且该bean中配置了对象的属性,再通过main方法进行调用我们可以看出实际效果,如:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
Person person = (Person) context.getBean("person");
// person.getWork();
System.out.println("未指定装配方式=====" + person);
System.out.println(person.getWork());
System.out.println(person.getAddress());
}
输出结果如下:
未指定装配方式=====Person{name='tomas', age=25, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}
Work{category='it', salary=20000.0}
Address{city='杭州', street='西湖区'}
2、byName:根据名称自动装配,必须将目标bean名称和类中属性名称和bean id设置的完全相同,否则将报错。
该模式根据bean中property中的name名称自动装配,如果目标bean的中name 与另一个bean中property的name相同,则自动装配这个bean到目标bean的property中(备注:目标bean节点通常需要指定自动装配的类型如:autowire="byName")
<?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="work" class="com.monkey.yb.autowire.Work">
<property name="category" value="it"></property>
<property name="salary" value="20000"></property>
</bean>
<bean id="address" class="com.monkey.yb.autowire.Address">
<property name="city" value="杭州"></property>
<property name="street" value="西湖区"></property>
</bean>
<bean id="person1" class="com.monkey.yb.autowire.Person" autowire="byName"></bean>
</beans>
再在main方法中调用:
package com.monkey.yb.autowire;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
Person person1 = (Person) context.getBean("person1");
System.out.println("指定byName装配方式=====" + person1);
}
}
实际输出结果如下:
指定byName装配方式=====Person{name='null', age=0, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}
3、byType:根据类型装配,若IOC容器中有多个月目标bean类型一致的bean,在这种情况下spring将无法判定哪个bean最合适该属性,所以不能执行自动装配。
如果不使用byName来进行装配,还可以使用byType来进行自动装配,它的大体意思就是另一个bean中拥有相同类型的属性自动装配到目标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="work" class="com.monkey.yb.autowire.Work">
<property name="category" value="it"></property>
<property name="salary" value="20000"></property>
</bean>
<bean id="address" class="com.monkey.yb.autowire.Address">
<property name="city" value="杭州"></property>
<property name="street" value="西湖区"></property>
</bean>
<bean id="person2" class="com.monkey.yb.autowire.Person" autowire="byType"></bean>
</beans>
再在main方法中调用:
package com.monkey.yb.autowire;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
Person person2 = (Person) context.getBean("person2");
System.out.println("指定byType装配方式=====" + person2);
}
}
实际输出结果如下:
指定byType装配方式=====Person{name='null', age=0, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}
上面的例子中,如果使用byType,则work和address中的bean id 都可以省略掉。