C02_D05_Understand_DI_ConstructorInjection-依赖注入:构造函数
//bean
public class Address {
private String province; //省
private String city; //市
private String detailedAddress; //详细地址
//如果使用构造函数注入属性的值,则需要生成对应的构造函数
@Override
public String toString() {
return "地址::" + province + "省" + city + "市" + detailedAddress;
}
//如果需要使用构造函数注入3个属性的值,则需要生成一个带3个参数的构造函数
//如果需要使用构造函数注入2个属性的值,则需要生成一个带2个参数的构造函数
//如果需要使用构造函数注入1个属性的值,则需要生成一个带1个参数的构造函数
public Address(String province, String city, String detailedAddress) {
this.province = province;
this.city = city;
this.detailedAddress = detailedAddress;
}
}
public class Company {
private String companyName; //公司名称
private Address companyAddress; //公司地址
private Set<String> branchNames; //分公司名称列表
private List<String> partnerNames; //合作伙伴名称列表
private List<Employee> employeeList; //公司员工列表
//Map集合的键和值都可以是任何类型,只不过通常键会选择用简单类型,如Integer或String等
private Map<String,Employee> branchManagers; //分公司负责人
/*Properties是一种特殊的Map集合,键和值的类型都是字符串*/
private Properties extraInfo1; //公司额外信息1
private Properties extraInfo2; //公司额外信息2
//如果想使用构造函数注入需要的属性的值,则需要生成包含对应个数参数的构造函数
public Company(String companyName, Address companyAddress, Set<String> branchNames, List<String> partnerNames,
List<Employee> employeeList, Map<String, Employee> branchManagers, Properties extraInfo1,
Properties extraInfo2) {
super();
this.companyName = companyName;
this.companyAddress = companyAddress;
this.branchNames = branchNames;
this.partnerNames = partnerNames;
this.employeeList = employeeList;
this.branchManagers = branchManagers;
this.extraInfo1 = extraInfo1;
this.extraInfo2 = extraInfo2;
}
public void showCompanyDetails() {
System.out.println("--------------------------公司信息--------------------------");
System.out.println("公司名称:" + companyName); //打印公司名称
System.out.println("公司地址:" + companyAddress); //打印公司地址
System.out.println(branchNames);
System.out.println(partnerNames);
System.out.println(employeeList);
System.out.println(branchManagers);
System.out.println(extraInfo1);
System.out.println(extraInfo2);
System.out.println("------------------------------------------------------------");
}
}
public class Employee {
//对于简单值,可以直接用value注入值
private String empId; // 员工编号
private String empName; // 员工姓名
private double empSalary; // 员工工资
//address属性是引用的另一个bean
private Address address; // 员工地址
//需要使用构造函数注入几个属性的值,则生成的构造函数就带几个参数
public Employee(String empId, String empName, double empSalary, Address address) {
this.empId = empId;
this.empName = empName;
this.empSalary = empSalary;
this.address = address;
}
public void showEmployeeDetails() {
System.out.println("---------------员工信息---------------");
// 输出员工基本信息
System.out.println("工号:" + empId);
System.out.println("姓名:" + empName);
System.out.println("工资:" + empSalary);
// 输出员工地址信息
System.out.println(address);
}
@Override
public String toString() {
return "[empId=" + empId + ", empName=" + empName + "]";
}
}
//config-beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 如果想使用c:这种写法,则需要引入c这个名称空间 -->
<!-- 对于constructor-arg标记,name指定构造函数的参数名,
value指定参数的值,
如果参数的值是引用的其他bean,
则使用ref属性指定引用的bean的id或name -->
<bean id="addr1" class="com.qdu.bean.Address">
<!-- 依赖注入可注入简单值(基本数据类型和字符串类型) -->
<!-- 如果使用constrcutor-arg标记,则调用对应的构造函数注入依赖的属性 -->
<!-- 简单值使用value指定属性值,引用的其他bean使用ref指定引用的bean的id或name -->
<!-- 这里的name是构造函数的参数名,不是属性的名称 -->
<constructor-arg name="province" value="山东" />
<constructor-arg name="city" value="青岛" />
<constructor-arg name="detailedAddress" value="宁夏路308号 青岛大学" />
</bean>
<!-- 构造函数的参数名也可不给,也就是name可以不指定,但是一定要确保参数的顺序正确 -->
<!-- 构造函数的参数可用name指定每个参数的名称,也可用index指定每个参数的索引,索引从0开始 -->
<bean id="addr2" class="com.qdu.bean.Address">
<constructor-arg index="0" value="山东" />
<constructor-arg index="1" value="临沂" />
<constructor-arg index="2" value="人民广场" />
</bean>
<!-- spring提供一种更简洁的依赖注入写法,和使用constructor-arg标记等效 -->
<!-- c:构造函数参数名=参数值 -->
<bean id="addr3" class="com.qdu.bean.Address" c:province="山东"
c:city="烟台" c:detailedAddress="芝罘区" />
<bean id="emp1" class="com.qdu.bean.Employee">
<!-- 使用constructor-arg标记,name属性的值是通过调用对应的setter方法注入 -->
<!-- 注入简单值,直接使用value属性指定要注入的值即可 -->
<constructor-arg name="empId" value="E001" />
<constructor-arg name="empName" value="小明" />
<constructor-arg name="empSalary" value="10000" />
<!-- 注入引用的其他bean,使用ref指定bean的id或name -->
<constructor-arg name="address" ref="addr1" />
</bean>
<!-- spring提供一种更简洁的写法:可使用“c:参数名”或“c:参数名-ref"的形式来实现注入 -->
<!-- 如果是简单值,直接写"c:参数名" 实现注入简单值 -->
<!-- 如果是引用的其他bean,需要写“c:参数名-ref”实现注入引用的其他bean -->
<bean id="emp2" class="com.qdu.bean.Employee" c:empId="E002"
c:empName="小红" c:empSalary="200000" c:address-ref="addr2" />
<bean id="company" class="com.qdu.bean.Company">
<constructor-arg name="companyName" value="Sunrise .Ltd" />
<constructor-arg name="companyAddress" ref="addr1" />
<!-- 注入set集合:使用set标记 -->
<constructor-arg name="branchNames">
<set>
<!-- 如果集合中是简单值,直接用value标记指定每个元素的值即可 -->
<!-- 如果集合中是其他bean,如Address,则需要使用<ref bean="id或name" /> -->
<!--
<ref bean="addr1" />
<ref bean="addr2" />
<ref bean="addr3" />
-->
<value>山东分公司</value>
<value>山西分公司</value>
<value>广东分公司</value>
<value>广西分公司</value>
</set>
</constructor-arg>
<!-- 如果集合中是简单值,直接使用value注入要注入的值即可 -->
<constructor-arg name="partnerNames">
<list>
<value>Oracle</value>
<value>Microsoft</value>
<value>IBM</value>
</list>
</constructor-arg>
<!-- 如果集合中是引用的其他bean,则使用ref标记, -->
<!-- 并使用bean属性指定要注入集合的bean的id或name即可 -->
<constructor-arg name="employeeList">
<list>
<ref bean="emp1" />
<ref bean="emp2" />
</list>
</constructor-arg>
<constructor-arg name="branchManagers">
<map>
<!-- Map集合中一个数据项,也就是一个键值对叫做一个entry -->
<!-- 如果键是简单值类型,使用key指定键的名称 -->
<!-- 如果键是引用的其他bean,使用key-ref指定键引用的其他bean的id或name -->
<!-- 如果值是简单值类型,使用value注入值 -->
<!-- 如果值是引用的其他bean,使用value-ref指定值引用的其他bean的id或name -->
<entry key="山东分公司" value-ref="emp1" />
<entry key="山西分公司" value-ref="emp2" />
</map>
</constructor-arg>
<constructor-arg name="extraInfo1">
<!-- 对于Properties类型的属性,可以使用props标记+prop标记实现注入 -->
<props>
<!-- Properties集合中的每个元素使用一个prop标记注入,key指定键的名称,prop标记的内容是要注入的值 -->
<prop key="type">Joint venture</prop>
<prop key="registeredCapital">2000000</prop>
<prop key="legalPerson">Allen</prop>
</props>
</constructor-arg>
<constructor-arg name="extraInfo2">
<!-- 对于Properties集合,也可直接使用value标记定义要注入的各个集合的值 -->
<!-- 在value中指定每个元素的键和值即可 -->
<value>
type=Joint venture
registeredCapital=2000000
legalPerson=Allen
</value>
</constructor-arg>
</bean>
</beans>
//main
public class Test1_UseDI_注入简单值 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("config/beans.xml");
Address addr1 = (Address) ctx.getBean("addr1");
System.out.println(addr1);
Address addr2 = (Address) ctx.getBean("addr2");
System.out.println(addr2);
Address addr3 = (Address) ctx.getBean("addr3");
System.out.println(addr3);
}
}
public class Test2_UseDI_注入简单值和引用的其他bean {
public static void main(String[] args) {
ApplicationContext ctx
= new ClassPathXmlApplicationContext("config/beans.xml");
Employee emp1 = (Employee) ctx.getBean("emp1");
emp1.showEmployeeDetails();
Employee emp2 = (Employee) ctx.getBean("emp2");
emp2.showEmployeeDetails();
}
}
/**
* *实现依赖注入-DI:注入集合(List、Set、|Map、Properties)
*
* @author 22-426
*/
public class Test3_UseDI_注入集合 {
public static void main(String[] args) {
ApplicationContext ctx
= new ClassPathXmlApplicationContext("config/beans.xml");
Company comp = (Company) ctx.getBean("company");
comp.showCompanyDetails();
}
}
我还以为开了Spring的课了 Orz