标签:sch his out contex 调用bean 设值 依赖 encoding ram
Spring的IOC(Inversion Of Control 控制反转)
是通过DI(Dependency Injection 依赖注入)
实现的,依赖注入在Spring主要有以下几种方式:
基于XML的依赖注入,指的是修改XML配置文件来实现依赖注入,主要包括setter设值注入和构造注入,另外还有一种自动注入,自动注入主要是针对引用类型属性的注入。
我们对XML依赖注入的讨论基于以下类和测试:
public class Staff {
private String name;
private int age;
private Company company;
public Staff() { }
public Staff(String name, int age, Company company) {
this.name = name;
this.age = age;
this.company = company;
}
public void setName(String name) { this.name = name; }
public void setAge(int age) { this.age = age; }
public void setCompany(Company company) { this.company = company; }
@Override
public String toString() {
return "Staff{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", company=" + company +
‘}‘;
}
}
public class Company {
private String name;
private String address;
public Company() { }
public Company(String name, String address) {
this.name = name;
this.address = address;
}
public void setName(String name) { this.name = name; }
public void setAddress(String address) { this.address = address; }
@Override
public String toString() {
return "Company{" +
"name=‘" + name + ‘\‘‘ +
", address=‘" + address + ‘\‘‘ +
‘}‘;
}
}
public class AppTest {
@Test
public void Test() {
String resource = "ApplicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(resource);
Staff staff = (Staff) context.getBean("Staff");
System.out.println(staff);
}
}
设值注入通过name
、value
和ref
属性。
name
: 属性名
value
: 简单类型值
ref
: 引用类型值
对简单类型(基本类型 + String)的属性,使用name
和value
属性:
<property name="属性名" value="属性值"/>
对引用类型的属性,使用name
和ref
属性:
<property name="属性名" ref="引用类型<bean>id属性值"/>
我们在Staff
和Company
的无参构造函数和各属性setter方法中打印一些提示信息,以便于我们观察整个注入流程:
public class Staff {
private String name;
private int age;
private Company company;
public Staff() {
System.out.println("Staff‘s non-arg constructor."); //提示信息
}
public Staff(String name, int age, Company company) {
this.name = name;
this.age = age;
this.company = company;
}
public void setName(String name) {
System.out.println("Staff‘s setName " + name); //提示信息
this.name = name;
}
public void setAge(int age) {
System.out.println("Staff‘s setAge " + age); //提示信息
this.age = age;
}
public void setCompany(Company company) {
System.out.println("Staff‘s setCompany " + company); //提示信息
this.company = company;
}
@Override
public String toString() {
return "Staff{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", company=" + company +
‘}‘;
}
}
public class Company {
private String name;
private String address;
public Company() {
System.out.println("Company‘s non-arg constructor."); //提示信息
}
public Company(String name, String address) {
this.name = name;
this.address = address;
}
public void setName(String name) {
System.out.println("Company‘s setName " + name); //提示信息
this.name = name;
}
public void setAddress(String address) {
System.out.println("Company‘s setAddress " + address); //提示信息
this.address = address;
}
@Override
public String toString() {
return "Company{" +
"name=‘" + name + ‘\‘‘ +
", address=‘" + address + ‘\‘‘ +
‘}‘;
}
}
运行观察:
TODO:至于对象的创建顺序,这里挖一个坑,以后再填。
name
属性(首字符变大写)拼接形成的方法名来调用setter方法,例如:<property name="age" value="19"/> <!--调用setAge方法-->
<property name="company" ref="Company"/> <!--调用setCompany方法-->
此时我们向Staff的
向Staff
类中增加setAny
方法(但没有any
属性):
运行观察:
构造注入通过name
、index
、value
和ref
属性。
name
: 形参名
index
: 形参位置, 从0开始
value
: 简单类型值
ref
: 引用类型值
对简单类型:
<constructor-arg name="形参名" value="形参值"/>
<constructor-arg index="形参位置,从0开始" value="形参值"/>
对引用类型:
<constructor-arg name="形参名" ref="引用类型<bean>id属性值"/>
<constructor-arg index="形参位置,从0开始" ref="引用类型<bean>id属性值"/>
我们在Staff
和Company
的有参构造函数中打印一些提示信息,以便于我们观察整个注入流程:
public class Staff {
private String name;
private int age;
private Company company;
public Staff() { }
public Staff(String name, int age, Company company) {
System.out.println("Staff‘s arg constructor."); //提示信息
this.name = name;
this.age = age;
this.company = company;
}
public void setName(String name) { this.name = name; }
public void setAge(int age) { this.age = age; }
public void setCompany(Company company) { this.company = company; }
@Override
public String toString() {
return "Staff{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", company=" + company +
‘}‘;
}
}
public class Company {
private String name;
private String address;
public Company() { }
public Company(String name, String address) {
System.out.println("Company‘s arg constructor."); //提示信息
this.name = name;
this.address = address;
}
public void setName(String name) { this.name = name; }
public void setAddress(String address) { this.address = address; }
@Override
public String toString() {
return "Company{" +
"name=‘" + name + ‘\‘‘ +
", address=‘" + address + ‘\‘‘ +
‘}‘;
}
}
运行观察:
TODO:至于对象的创建顺序,这里挖一个坑,以后再填。
自动注入是针对引用类型属性的注入。当我们的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="xxx" class="xxx.xxx.xxx">
<property name="..." ref="..."/>
<property name="..." ref="..."/>
<property name="..." ref="..."/>
<property name="..." ref="..."/>
...
</bean>
<bean id="xxx" class="xxx.xxx.xxx">
...
</bean>
<bean id="xxx" class="xxx.xxx.xxx">
...
</bean>
<bean id="xxx" class="xxx.xxx.xxx">
...
</bean>
...
</beans>
ref
引用的都是其他byName
和byType
两种方法。
为了完成此部分的分析,我们添加一个Company
的子类InternetCompany
:
public class InternetCompany extends Company {
public InternetCompany() {
System.out.println("InternetCompany‘s non-arg constructor");
}
public InternetCompany(String name, String address) {
super(name, address);
System.out.println("InternetCompany‘s arg constructor");
}
}
类型同源:
byName
byName通过在autowire
属性设为byName
实现,Spring会查找和属性同名的
byType
byType通过在autowire
属性设为byType
实现,Spring会查找同源bean,并注入。不可以有多个同源
TODO:填个坑
标签:sch his out contex 调用bean 设值 依赖 encoding ram
原文地址:https://www.cnblogs.com/YuHover/p/SpringDI.html