快速创建一个spring项目
新建一个工程,选择spring,勾选“Create empty spring-config.xml”,Libraries选择Download会自动下载所需包。
创建HelloSpring
package com.Re;
public class HelloSpring {
private String name;
public void setName(String name){
this.name=name;
}
public void printHello(){
System.out.println("Spring say Hello"+name);
}
}
编辑spring-config.xml
创建一个测试类
package com.Re;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpringTest {
public static void main(String[] args) {
//以classpath路径下的"spring-config.xml"创建ApplicationContext实例
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//在bean工厂获取id为"helloBean"的类
HelloSpring helloSpring = (HelloSpring) context.getBean("helloBean");
//调用方法,bean工厂会将参数赋值给方法
helloSpring.printHello();
}
}
项目结构及结果
自动装配Bean
创建Person类
package com.Re.autowiredDemo;
public class Person {
private String hei;
public String getHei() {
return hei;
}
public void setHei(String hei) {
this.hei = hei;
}
@Override
public String toString() {
return "Person{" +
"hei='" + hei + '\'' +
'}';
}
}
创建Customer类
package com.Re.autowiredDemo;
public class Customer {
private Person person;
//无参构造
public Customer() {
}
//带参构造
public Customer(Person person) {
this.person = person;
}
public void setPerson(Person person) {
this.person = person;
}
}
创建测试类Test.java
package com.Re.autowiredDemo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Customer customer = (Customer) context.getBean("customer");
System.out.println(customer);
}
}
第一种:默认的ref
运行Test.java,验证自动装配成功
流程猜想
执行: ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
此时根据路径找到配置文件,创建了一个上下文对象
执行: Customer customer = (Customer) context.getBean("customer");
- 此时通过对象获取配置文件里【id=customer】的配置,
- 根据配置自动生成Person对象(property name="person"的作用)
- 通过 ref="person"连接到【id=person】的配置,
- 通过【property name="hei" value="hello"】给Person类里的hei变量赋值“hello”
- 然后通过Person.java里重写的toString获得返回值“Person{hei='hello'}”
- 然后回传给Customer里的person变量
- 然后通过Customer.java里重写的toString获得返回值“Customer{person=Person{hei='hello'}}”
第二种:byName
如果一个bean的名称与其他bean属性的名称是一样的,那么将自动装配它。例子:Customer.java 增加一个“address”属性,那么Spring会在配置文件里寻找【id=address】的bean,如果找到了就自动装配,如果没找到,就什么都不做
修改Customer
package com.Re.autowiredDemo;
public class Customer {
//新增一个adress参数
private Address address;
private Person person;
//无参构造
public Customer() {
}
//带参构造
public Customer(Person person) {
this.person = person;
}
public Customer(Address address) {
this.address = address;
}
public void setPerson(Person person) {
this.person = person;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Customer{" +
"address=" + address +
", person=" + person +
'}';
}
}
新建Address.java
package com.Re.autowiredDemo;
public class Address {
private String myaddress;
public void setMyaddress(String myaddress) {
this.myaddress = myaddress;
}
@Override
public String toString() {
return "Address{" +
"myaddress='" + myaddress + '\'' +
'}';
}
}
修改配置文件
运行测试Test.java
修改配置文件,将Address的id改一下,造成与Customer属性不一致的情况,测试验证找不到bean。
运行测试Test.java,address=null
第三种:byType
类型自动装配,通过判断一个bean属性的数据类型与其他bean的数据类型相同,自动装配
拿上面的例子说,Customer类里的属性address的类型是“Address”,与“Address” bean中的数据类型是一样的,所以Spring会通过setter方法自动装配 setAddress(Address address)
修改配置文件
运行测试Test.java
如果配置文件里创建了两个一样类型的bean,就会装配失败,程序不知道要选择哪个。
所以,如果使用按类型自动装配,那么要确保bean只有唯一一个数据类型声明。