Spring之 IOC的继续—bean标签 --依赖注入 DI— 02
BeanFactory 和 ApplicationContext 的区别
BeanFactory 才是 Spring 容器中的顶层接口。ApplicationContext 是它的子接口。BeanFactory 和 ApplicationContext 的区别:创建对象的时间点不一样。ApplicationContext:只要一读取配置文件,默认情况下就会创建BeanFactory:什么使用什么时候创建对象。
ApplicationContext 接口的实现类ClassPathXmlApplicationContext:它是从类的根路径下加载配置文件 推荐使用这种FileSystemXmlApplicationContext:它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。AnnotationConfigApplicationContext:当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。
spring 的依赖注入
依赖注入的概念
依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。
我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。
ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。
编码程序呈现----------》
创建 maven的 module
maven 的 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
com.fhw
fhw01_05DI
1.0-SNAPSHOT
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
bean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!--constructor-arg构造函数 的
优势 : 必须要注入所有的 参数 否则 失败
弊端:用不到的参数也要提供 死板 -->
<constructor-arg name="name" value="fhw"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="birthday" ref="date"></constructor-arg>
<!-- DI :之set 注入===常用的方式
标签: property 在bean 里
property 属性:
name: 最直接 最常用 : 写上 set的方法名称( 不写set这几个字 , 首字母就不大写了
由于是编辑器 生成 的一举 的就是属性名 所以就 直接的 =====》写属性名即可 )
变量名称=======》这是指定 参数的赋值
value:要注入 的元素
ref: 引用关联的bean对象
优势: 没有明确的限制 ,直接用默认构造函数
劣势:成员 必须有值 , 无法保持 一定注入 获取对象时 有时set 没有执行
调用对象的时候 可能 通过构造函数 已用完了,
-->
<!-- 复杂集合 的DI
array List Set :的标签可以互换
Map 与 properties 结构 相同 标签可以互换
概括为:2 种 记好 单列 或 双列 各自的标签 可以互换
-->
<bean id="DI_Container" class="com.fhw.service.impl.fhw03_DI_Container">
<!--值数据 单列集合 -->
<property name="myStr">
<array>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</array>
</property>
<property name="myList">
<list>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</list>
</property>
<property name="mySet">
<set>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</set>
</property>
<!-- 映射关系数据集合==== 双列集合-->
<property name="myMap">
<map ><!-- map的 2个方式 -->
<entry key="map1" value="mmm" ></entry>
<entry key="map2"><value>aaa</value></entry>
</map>
</property>
<property name="myPros">
<props ><!-- Properties的 方式 -->
<prop key="Properties01">ppp</prop>
<prop key="Properties02">rrr</prop>
</props>
</property>
</bean>
service里的代码
构造方法的注入 方式*
package com.fhw.service.impl;
import java.util.Date;
public class fhw01_DI_constructor {
private String name ;
private int age;
private Date birthday;
/*注入 注意的就是 数据类型 type : 基本数据 int 字符串String ,其他bean类型 date */
public fhw01_DI_constructor (String name,Integer age,Date birthday){
this.name=name;
this.age=age;
this.birthday=birthday;
}
public void saveAccount() {
System.out.println("构造方法 的方式执行了"+name+"======"+age+"====="+birthday);
}
}
set方法的方式
public class fhw02_DI_set {
private String name ;
private int age;
private Date birthday;
/*注入 注意的就是 数据类型 type : 基本数据 int 字符串String ,其他bean类型 date /
/ 注入 只需要 set方法即可 */
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void setDI() {
System.out.println("set 方法执行了"+name+"======"+age+"====="+birthday);
}
}
集合容器的方式
package com.fhw.service.impl;
import java.util.*;
public class fhw03_DI_Container {
private String[] myStr;
private List myList;
private Set mySet;
private Map<String, String> myMap;
private Properties myPros;
public void setMyStr(String[] myStr) {
this.myStr = myStr;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyPros(Properties myPros) {
this.myPros = myPros;
}
public void myCollection() {
System.out.println("容器数组:"+ Arrays.toString(myStr));
System.out.println("容器list:"+myList);
System.out.println("容器Set:"+mySet);
System.out.println("容器Map:"+myMap);
System.out.println("容器Properties:"+myPros);
}
}
测试
package com.fhw.ui;
import com.fhw.service.impl.fhw01_DI_constructor;
import com.fhw.service.impl.fhw02_DI_set;
import com.fhw.service.impl.fhw03_DI_Container;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
/**
*
-
@param args
*/
public static void main(String[] args) {//获取 spring 的核心容器对象: 参数就是 bean.xml
ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);
// ApplicationContext acFile= new FileSystemXmlApplicationConext("");
fhw01_DI_constructor as = (fhw01_DI_constructor)ac.getBean(“fhw01”);//要强转
// IAccountDao adao=ac.getBean(“accountDao”,IAccountDao.class);
as.saveAccount();
fhw02_DI_set set1=(fhw02_DI_set)ac.getBean(“DI_set”);
set1.setDI();
fhw03_DI_Container container = (fhw03_DI_Container)ac.getBean(“DI_Container”);
container.myCollection();
}
}
附 : 使用 p 名称空间注入数据(本质还是调用 set 方法)
此种方式是通过在 xml 中导入 p 名称空间,使用 p:propertyName 来注入数据,它的本质仍然是调用类中的set 方法实现注入功能。Java 类代码:/*** 使用 p 名称空间注入,本质还是调用类中的 set 方法*/public class AccountServiceImpl4 implements IAccountService {private String name;private Integer age;private Date birthday;public void setName(String name) {this.name = nam
}public void setAge(Integer age) {this.age = age;}public void setBirthday(Date birthday) {this.birthday = birthday;}@Overridepublic void saveAccount() {System.out.println(name+","+age+","+birthday);}
xml 文件代码:ans xmlns=“http://www.springframework.org/schema/beans” xmlns:p=“http://www.springframework.org/schema/
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