Study(2) SpringIOC 基于xml方式依赖注入
1.原始关系(非IOC)
对象之间依赖关系由对象自己来建立
A—->B
A
B b = new B();
b.f1();
B
f1();
C
f1();
2.IOC
(1).Ioc (Inversion of controll 控制反转):对象之间的依赖关系由容器建立
(2).DI (Dependency Injection 依赖注入):容器通过调用对象提供的set方法或者构造器来建立依赖关系
注:IOC是目标,DI是手段
3.bean注入(set方式,构造器方式)
方式一:set方法依赖注入(A—->B)
property元素:表示使用set方法来注入依赖关系,其中name属性指定属性名
ref 属性指定属性值(是被注入的bean的id)(不推荐,若想 A—-C 代码改动很大)
(1).建立 A,B对象
public class B {
public B(){
System.out.println("B()");
}
public void f1(){
System.out.println("B-f1()");
}
}
public class A {
private B b;
public void setB(B b){
System.out.println("setB()");
this.b = b;
}
public A(){
System.out.println("A()");
}
public void exeute(){
System.out.println("exeute()");
b.f1();
}
}(2).ioc.xml
<bean id="b1" class="cn.com.sinodata.Ioc.B"></bean>
<!--
property元素:表示使用set方法来注入依赖关系,其中name属性指定属性名
ref属性指定属性值(是被注入的bean的id)
-->
<bean id="a1" class="cn.com.sinodata.Ioc.A">
<property name="b" ref="b1"></property>
</bean>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("IOC.xml");
A a1 = applicationContext.getBean("a1", A.class);
a1.exeute();(4).spring容器运行流程说明
spring容器启动后,会读配置文件(ioc.xml),创建所有单例(scope=”singleton”)对象,检测到 A 对象 中property元素时,容器会使用set方法注入 B 对象
方式一:set方法依赖注入(A <—-C)
property元素:表示使用set方法来注入依赖关系,其中name属性指定属性名
ref 属性指定属性值(是被注入的bean的id)(推荐此方法,若想 A <—-B 或者 A<—-C ,代码只需改动配置文件即可)
若想代码变化少,建立接口,让 B 和 C 都实现这个接口
代码优化:
(1).建立 A,B,C对象
public interface BC {
public void f1();
}
public class B implements BC{
public B(){
System.out.println("B()");
}
public void f1(){
System.out.println("B-f1()");
}
}
public class C implements BC{
public C(){
System.out.println("C()");
}
public void f1(){
System.out.println("C-f1()");
}
}
public class A {
private BC bc;
public void setBc(BC bc){
System.out.println("setBC()");
this.bc = bc;
}
public A(){
System.out.println("A()");
}
public void exeute(){
System.out.println("exeute()");
bc.f1();
}
}(2).ioc.xml
<bean id="b1" class="cn.com.sinodata.Ioc.B"></bean>
<!--
property元素:表示使用set方法来注入依赖关系,其中name属性指定属性名
ref属性指定属性值(是被注入的bean的id)
-->
<bean id="c1" class="cn.com.sinodata.Ioc.C"></bean>
若 A <-----B 使用
<bean id="a1" class="cn.com.sinodata.Ioc.A">
<property name="bc" ref="b1"></property>
</bean>
若 A <-----C 使用
<bean id="a1" class="cn.com.sinodata.Ioc.A">
<property name="bc" ref="c1"></property>
</bean>方式二:构造器方式注入
constructor-arg元素:用来配置构造器方式的注入,
ref: 指定构造器注入的bean的Id
index: 指定参数下标(从0开始)(1).建立 A,B,C对象
public interface BC {
public void f1();
}
public class B implements BC{
public B(){
System.out.println("B()");
}
public void f1(){
System.out.println("B-f1()");
}
}
public class C implements BC{
public C(){
System.out.println("C()");
}
public void f1(){
System.out.println("C-f1()");
}
}
public class A {
private BC bc;
public A(BC bc){
this.bc = bc;
}
public A(){
System.out.println("A()");
}
public void excute(){
System.out.println("A-excute()");
bc.f1();
}
}(2).ioc.xml
<bean id="b2" class="cn.com.sinodata.IocCons.B"></bean>
<bean id="c2" class="cn.com.sinodata.IocCons.C"></bean>
<!--
constructor-arg元素:用来配置构造器方式的注入,
ref: 指定构造器注入的bean的Id
index: 指定参数下标(从0开始)
-->
<bean id="a2" class="cn.com.sinodata.IocCons.A">
<constructor-arg index="0" ref="c2"></constructor-arg>
</bean>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("IocCon.xml");
cn.com.sinodata.IocCons.A a2 = applicationContext.getBean("a2", cn.com.sinodata.IocCons.A.class);
a2.excute();4.自动装配
自动装配:spring容器根据某种规则,自动建立对象之间的依赖关系
注意:
(1).默认情况下,容器不会自动装配的
(2).可以通过指定autowire属性,告诉容器进行自动装配(容器仍然需要通过调用set方法或者构造器来完成依赖关系的建立)
autowire属性:表示让容器自动装配,该属性有三个值
byName:(优先使用)
容器依据属性名查找对应的bean,调用对应的set方法完成注入。
注:
a: 如果找不到对应的bean.注入null
b: 不可能找到多个符合条件的bean,根据(id)
byType:
容器依据属性类型查找对应的bean,然后调用对应的set方法来完成注入
注:
a: 如果找不到对应的bean.注入null
b: 有可能找到多个符合条件的bean,此时会报错 ,根据(class类型)
constructor:
容器依据属性名查找对应的bean,调用对应的构造器完成注入。(1).建立Waiter,Restarant类
public class Waiter {
public Waiter(){
System.out.println("Waiter()");
}
}
public class Restarant {
private Waiter waiter;
public void setWaiter(Waiter waiter) {
System.out.println("setWaiter");
this.waiter = waiter;
}
public Restarant(){
System.out.println("Restarant()");
}
@Override
public String toString() {
return "[Waiter="+this.waiter+"]";
}
}(2).IocCon.xml
<!--
autowire属性:表示让容器自动装配,该属性有三个值
byName:容器依据属性名查找对应的bean,调用对应的set方法完成注入。
注:
a: 如果找不到对应的bean.注入null
b: 不可能找到多个符合条件的bean,根据(id)
byType: 容器依据属性类型查找对应的bean,然后调用对应的set方法来完成注入
注:
a: 如果找不到对应的bean.注入null
b: 有可能找到多个符合条件的bean,此时会报错 ,根据(class类型)
constructor: 容器依据属性名查找对应的bean,调用对应的构造器完成注入。
-->
<bean id="waiter" class="cn.com.sinodata.IocCons.Waiter"></bean>
<bean id="restarant" class="cn.com.sinodata.IocCons.Restarant" autowire="byName"></bean>
<bean id="restarant" class="cn.com.sinodata.IocCons.Restarant" autowire="byType"></bean>
<bean id="restarant" class="cn.com.sinodata.IocCons.Restarant" autowire="constructor"></bean>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("IocCon.xml");
Restarant restarant = applicationContext.getBean("restarant", Restarant.class);
System.out.println(restarant.toString());5.Spring 注入值
(1).新建ValueBean
public class ValueBean {
private String name;
private int age;
private List<String> city;
private Set<String> interest;
private Map<String,Double> score;
private Properties properties;
public ValueBean(){
System.out.println("ValueBean()");
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setScore(Map<String, Double> score) {
this.score = score;
}
public void setInterest(Set<String> interest) {
this.interest = interest;
}
public void setCity(List<String> city) {
this.city = city;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "ValueBean{" +
"name='" + name + '\'' +
", age=" + age +
", city=" + city +
", interest=" + interest +
", score=" + score +
", properties=" + properties +
'}';
}
}(2).value.xml
注入基本类型的值
<bean id="valueBean" class="cn.com.sinodata.Value.ValueBean">
<property name="name" value="zhangsan"></property>
<property name="age" value="12"></property>
</bean>注入集合类型的值(List Set Map Properties)
<bean id="valueBean" class="cn.com.sinodata.Value.ValueBean">
<property name="city" >
<list>
<value>北京</value>
<value>深圳</value>
<value>上海</value>
</list>
</property>
<property name="interest">
<set>
<value>唱歌</value>
<value>跳舞</value>
<value>唱歌</value>
</set>
</property>
<property name="score">
<map>
<entry key="数学" value="23.0"></entry>
<entry key="语文" value="33.2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>引用的方式注入集合类型的值
加入
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
<!--将集合类型的值配置成一个bean-->
<util:list id="cityBean">
<value>北京</value>
<value>深圳</value>
<value>上海</value>
</util:list>
<util:set id="interestBean">
<value>唱歌</value>
<value>跳舞</value>
<value>唱歌</value>
</util:set>
<util:map id="scoreBean">
<entry key="数学" value="23.0"></entry>
<entry key="语文" value="33.2"></entry>
</util:map>
<util:properties id="propertiesBean">
<prop key="username">root</prop>
<prop key="password">123456</prop>
</util:properties>
<!--引用的方式注入集合类型的值-->
<bean id="valueBean2" class="cn.com.sinodata.Value.ValueBean">
<property name="city" ref="cityBean"/>
<property name="properties" ref="propertiesBean"/>
<property name="score" ref="scoreBean"/>
<property name="interest" ref="interestBean"/>
</bean>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("value.xml");
ValueBean valueBean = applicationContext.getBean("valueBean", ValueBean.class);
System.out.println(valueBean.toString());
// 引用的方式注入集合类型的值
ValueBean valueBean = applicationContext.getBean("valueBean2", ValueBean.class);
System.out.println(valueBean.toString());6.读取properties文件的内容
(1).新建config.properties文件
pagesize=10(2).value.xml
读取properties文件内容,
classpath: 按照类路径来搜索
spring容器会根据路径找到对应的properties文件,然后读取该文件的内容到Properties对象
<util:properties id="config" location="classpath:config.properties"/>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("value.xml");
System.out.println(applicationContext.getBean("config"));7.使用spring表达式
可以使用spring表达式读取其他bean的属性,语法类似于el表达式
valueBean.name
valueBean.city[0] valueBean为ValueBean的id,city为ValueBean的属性,[0]为list类型city属性的下标(1).新建ValueBean和SeplBean
public class ValueBean {
private String name;
private List<String> city;
private Map<String,Double> score;
public ValueBean(){
System.out.println("ValueBean()");
}
public String getName() {
return name;
}
public List<String> getCity() {
return city;
}
public Map<String, Double> getScore() {
return score;
}
public void setScore(Map<String, Double> score) {
this.score = score;
}
public void setCity(List<String> city) {
this.city = city;
}
public void setName(String name) {
this.name = name;
}
}
public class SeplBean {
private String name;
private String city;
private Double score;
private String pageSize;
public SeplBean(){
System.out.println("seplbean()");
}
public void setScore(Double score) {
this.score = score;
}
public void setCity(String city) {
this.city = city;
}
public void setName(String name) {
this.name = name;
}
public void setPageSize(String pageSize) {
this.pageSize = pageSize;
}
@Override
public String toString() {
return "SeplBean{" +
"name='" + name + '\'' +
", city='" + city + '\'' +
", score=" + score +
", pageSize='" + pageSize + '\'' +
'}';
}
}
新建 seplutrl.properties 文件 ,pagesize=10(2).sepl.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"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
//此类中必须包含get set方法,否则,使用spring表达式访问不到属性值
<bean id="valueBean" class="cn.com.sinodata.Value.ValueBean">
<property name="name" value="eee"/>
<property name="score">
<map>
<entry key="math" value="233"></entry>
</map>
</property>
<property name="city" ref="cityutil"/>
</bean>
<util:list id="cityutil">
<value>中国北京</value>
<value>中国深圳</value>
</util:list>
<util:properties id="seplutil" location="classpath:seplutrl.properties"/>
<bean id="seplBean" class="cn.com.sinodata.SeplBean">
<property name="pageSize" value="#{seplutil.pagesize}"/>
<property name="city" value="#{valueBean.city[0]}"/>
<property name="score" value="#{valueBean.score.math}"/>
<property name="name" value="#{valueBean.name}"/>
</bean>
</beans>(3).测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("sepl.xml");
SeplBean seplBean = applicationContext.getBean("seplBean", SeplBean.class);
System.out.println(seplBean.toString());
文章标题:Study(2) SpringIOC 基于xml方式依赖注入
发布时间:2020-04-23, 17:43:34
最后更新:2020-04-23, 17:43:34