Spring4笔记4--基于XML的DI(依赖注入)
基于XML的DI(依赖注入):
Bean 实例在调用无参构造器创建了空值对象后,就要对 Bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:设值注入、构造注入。还有另外一种,实现特定接口注入。由于这种方式采用侵入式编程,污染了代码,所以几乎不用。
注入分类:
(1) 设值注入:
设值注入是指,通过 setXXX() 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
<?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="mySchool" class="com.tongji.di01.School">
<property name="name" value="清华大学"/>
</bean>
<bean id="student" class="com.tongji.di01.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school" ref="mySchool"/>
</bean>
</beans>
(2) 构造注入:
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。
<?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="mySchool" class="com.tongji.di02.School">
<property name="name" value="清华大学"/>
</bean>
<bean id="student" class="com.tongji.di02.Student">
<constructor-arg name="name" value="李四"/>
<constructor-arg name="age" value="24"/>
<constructor-arg name="school" ref="mySchool"/> <!--<constructor-arg index="0" value="李四"/>
<constructor-arg index="1" value="24"/>
<constructor-arg index="2" ref="mySchool"/>
--> <!--<constructor-arg value="李四"/>
<constructor-arg value="24"/>
<constructor-arg ref="mySchool"/>
--> </bean>
</beans>
命名空间注入:
对于设值注入与构造注入,在配置文件中,除了使用<property/>或<constructor-arg/>标签外,还可使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分为 p 命名空间注入与 c 命名空间注入。
p 命名空间注入:采用设值注入方式,故需要有相应的 setXXX()
c 命名空间注入:采用构造注入方式,故需要有相应的构造器
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="mySchool" class="com.tongji.di03.School" p:name="北京大学"/> <bean id="student" class="com.tongji.di03.Student" p:name="王五" p:age="25" p:school-ref="mySchool"/> </beans>
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="mySchool" class="com.tongji.di04.School">
<property name="name" value="清华大学"/>
</bean>
<bean id="student" class="com.tongji.di04.Student" c:name="赵六" c:age="26" c:school-ref="mySchool"/> </beans>
注意添加的约束:xmlns:p="http://www.springframework.org/schema/p" 和 xmlns:c="http://www.springframework.org/schema/c"
集合属性的注入:
<?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="mySchool1" class="com.tongji.di05.School">
<property name="name" value="清华大学"/>
</bean>
<bean id="mySchool2" class="com.tongji.di05.School">
<property name="name" value="北京大学"/>
</bean> <bean id="some" class="com.tongji.di05.Some">
<property name="names">
<array>
<value>张三</value>
<value>赵四</value>
<value>王五</value>
</array>
</property>
<property name="schools">
<list>
<ref bean="mySchool1"/>
<ref bean="mySchool2"/>
</list>
</property>
<property name="mySets">
<set>
<value>中国</value>
<value>上海</value>
<value>黄渡理工大学</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="QQ" value="7654321"/>
<entry key="Email" value="7654321@qq.com"/>
</map>
</property>
<property name="myProes">
<props>
<prop key="address">上海曹安公路</prop>
<prop key="phone">123456778</prop>
</props>
</property>
</bean>
</beans>
对域属性的自动注入:
对于域属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置autowire 属性值,为域属性进行隐式自动注入。根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType:根据类型自动注入
byName:当配置文件中被调用者 Bean 的 id 值与代码中调用者 Bean 类的属性名相同时,可使用byName 方式,让容器自动将被调用者 Bean 注入给调用者 Bean。容器是通过调用者的 Bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。
<?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="school" class="com.tongji.di06.School">
<property name="name" value="清华大学"/>
</bean> <!-- byName方式域属性自动注入,要求自动注入的bean的id与被注入的属性名相同 -->
<bean id="student" class="com.tongji.di06.Student" autowire="byName">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
</beans>
byType:使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 Bean 类的某域属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 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="mySchool" class="com.tongji.di07.School">
<property name="name" value="清华大学"/>
</bean> <!-- byType方式域属性自动注入,要求容器中与被注入属性类型具有is-a关系的Bean,只能有一个 -->
<bean id="student" class="com.tongji.di07.Student" autowire="byType">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
</beans>
使用SPEL表达式注入:(需要进一步学习SPEL表达式)
SPEL,Spring Expression Language,即 Spring EL 表达式语言。即,在 Spring 配置文件中为 Bean 的属性注入值时,可直接使用 SPEL 表达式计算的结果。SPEL 表达式以#开头,后跟一对大括号。用法: <bean id=“abc” value=“#{…}”/>。
<?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="person" class="com.tongji.di08.Person">
<property name="pname" value="李四"/>
<property name="page" value="#{T(java.lang.Math).random() * 80}"/>
</bean> <bean id="student" class="com.tongji.di08.Student">
<property name="name" value="#{person.pname}"/>
<property name="age" value="#{person.computeAge()}"/>
</bean>
</beans>
使用内部 Bean 注入 :
若不希望代码直接访问某个 bean,即,在代码中通过 getBean 方法获取该 Bean 实例, 则可将该 Bean 的定义放入调用者 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="mySchool" class="com.tongji.di09.School">
<property name="name" value="清华大学"/>
</bean>
--> <bean id="student" class="com.tongji.di09.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school">
<bean class="com.tongji.di09.School">
<property name="name" value="清华大学"/>
</bean>
</property>
</bean>
</beans>
使用同类抽象 Bean 注入:
当若干 Bean 实例同属于一个类,且这些实例的属性值又有相同值时,可以使用抽象Bean,以简化配置文件。
抽象 Bean 是用于让其它 bean 继承的。这个 bean 在 Bean 类中是不能通过 getBean 方法获取的。设置 abstract 属性为 true 来指明该 bean 为抽象 bean,默认值为 false。不过,该 bean 不为抽象 bean 时,也可被继承。只不过,在应用中,用于被继承的 bean 一般为抽象 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 -->
<bean id="baseStudent" class="com.tongji.di10.Student" abstract="true">
<property name="school" value="清华大学"/>
<property name="department" value="计算机学院"/>
</bean> <bean id="student1" parent="baseStudent">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
<bean id="student2" parent="baseStudent">
<property name="name" value="李四"/>
<property name="age" value="24"/>
</bean>
<bean id="student3" parent="baseStudent">
<property name="name" value="王五"/>
<property name="age" value="25"/>
</bean>
</beans>
使用异类抽象 Bean 注入:
当若干不同的类对象具有相同的属性,且其值也相同时,可使用异类抽象 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 -->
<bean id="Person" abstract="true">
<property name="school" value="清华大学"/>
<property name="department" value="计算机学院"/>
</bean> <bean id="student" class="com.tongji.di11.Student" parent="Person">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean> <bean id="teacher" class="com.tongji.di11.Teacher" parent="Person">
<property name="name" value="李四"/>
<property name="workAge" value="24"/>
</bean>
</beans>
为应用指定多个 Spring 配置文件:
在实际应用里,随着应用规模的增加,系统中 Bean 数量也大量增加,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将 Spring 配置文件分解成多个配置文件。
(1) 以配置文件数组方式实现:将所有配置文件的路径定义为一个 String 数组,并将其作为容器初始化参数出现。其将与可变参的容器构造器匹配。
package com.tongji.di12; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test01() {
//创建容器
String resource1 = "com/tongji/di12/spring-base.xml";
String resource2 = "com/tongji/di12/spring-beans.xml"; String[] resources = {resource1, resource2};
@SuppressWarnings("resource")
ApplicationContext ac = new ClassPathXmlApplicationContext(resources); Student student = (Student) ac.getBean("student");
System.out.println(student); Teacher teacher = (Teacher) ac.getBean("teacher");
System.out.println(teacher);
} }
第12、13行的配置文件为并列关系,不分主次。
(2) 以父子配置文件方式实现 :
各配置文件中有一个总文件,总配置文件将各其它子文件通过<import/>引入。在 Java代码中只需要使用总配置文件对容器进行初始化即可。
<?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"> <import resource="classpath:com/tongji/di13/spring-base.xml"/> <!-- 注意classpath -->
<import resource="classpath:com/tongji/di13/spring-beans.xml"/> <!-- 也可使用通配符*。但,此时要求父配置文件名不能满足*所能匹配的格式,否则将出现循环递归包含 --> </beans>
package com.tongji.di13; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test01() {
//创建容器
String resource = "com/tongji/di13/applicationContext.xml"; @SuppressWarnings("resource")
ApplicationContext ac = new ClassPathXmlApplicationContext(resource); Student student = (Student) ac.getBean("student");
System.out.println(student); Teacher teacher = (Teacher) ac.getBean("teacher");
System.out.println(teacher);
} }
Spring4笔记4--基于XML的DI(依赖注入)的更多相关文章
- 三大框架 之 Spring(IOC控制反转、DI依赖注入)
目录 常用词汇 left join与left outer join的区别 Struts2的标签库导入 Spring Spring概述 什么是Spring spring特点 下载 IOC 什么IOC 传 ...
- Spring:(二)DI依赖注入方式
DI 依赖注入 DI(Dependency Injection)依赖注入,说简单一点就将类里面的属性在创建类的过程中给属性赋值,即将对象依赖属性(简单值,集合,对象)通过配置设值给该对象. 属性注入的 ...
- Java开发学习(六)----DI依赖注入之setter及构造器注入解析
一.DI依赖注入 首先来介绍下Spring中有哪些注入方式? 我们先来思考 向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 依赖注入描述了在容器中建立bean与bean之间的依赖关 ...
- 初识Spring框架实现IOC和DI(依赖注入)
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的, IoC是 ...
- 谈谈php里的IOC控制反转,DI依赖注入
理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...
- Spring详解(三)------DI依赖注入
上一篇博客我们主要讲解了IOC控制反转,也就是说IOC 让程序员不在关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建.初始化.销毁等工作交给spring容器来做.那么创建对象的时候,有可 ...
- 一) Spring 介绍、IOC控制反转思想与DI依赖注入
一.spring介绍1.IOC反转控制思想(Inversion of Control)与DI依赖注入(Dependency Injection)2.AOP面向切面的编程思想与动态代理3.作用:项目的粘 ...
- JAVAWEB 一一 Spirng(框架,IOC控制反转,DI依赖注入)
jar包 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <bea ...
- AutoFac IoC DI 依赖注入
AutoFac IoC DI 依赖注入 记录点点滴滴知识,为了更好的服务后来者! 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌 ...
随机推荐
- 卸载Visual Studio最佳方法难道真的是重装系统?
卸载Visual Studio最佳方法难道真的是重装系统? 卸载Visual Studio最佳方法难道真的是重装系统? 使用TotalUninstaller貌似也没有效果,默认卸载的,程序列表里面还是 ...
- SPOJ_VLATTICE
题目是给你一个空间,和一个点(n,n,n),求从原点出发能够直接接触多少个点(不经过任何一个点)? 典型的mobius反演即可. 首先,ans=3,因为(1,0,0),(0,1,0),(0,0,1)这 ...
- 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化
挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...
- 51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题
51nod 1563 坐标轴上的最大团 坐标轴上有n个点,每个点有一个权值.第i个点的坐标是 xi ,权值是 wi .现在对这些点建图.对于点对 (i,j) ,如果 |xi−xj|≥wi+wj ,那么 ...
- Java入门:注册模块的实现
1.主活动图 用户选择注册选项,进入注册界面,开始输入注册信息,到最后完成注册.具体的活动图如下: 以上活动图中,矩形框里的操作不是在一个类里面实现的,而是通过Form类和UserService类来实 ...
- GO_01:Mac之Go语言Idea环境配置
声明:本人所使用的是Mac Pro 安装开始 1. 首先将 GO 基础组件安装好,就好似 java 中的 jdk.当然,安装的时候需要到官网去下载,这一步难倒了好多无法FQ的同学们,故这里我将我这边下 ...
- python内置数据结构方法的时间复杂度
转载自:http://www.orangecube.net/python-time-complexity 本文翻译自Python Wiki 本文基于GPL v2协议,转载请保留此协议. 本页面涵盖了P ...
- day14 多态与抽象
多态:相同的行为,不同的实现. 多态分为:静态多态和动态多态. 静态多态:在编译期即确定方法的实现和效果.——使用重载实现 动态多态:运行后才能确定方法的实现和执行效果.——使用动态绑定和重写实现 动 ...
- day10 浅谈面向对象编程
面向对象编程:第一步找名词,名词是问题域中的. 第二步概括名词设计成类.某些名词可以浓缩包含到其它名词中,成为其属性. 第三步找动词,动词也是问题域中的. 第四步概括动词设计成方法.动作的产生往往 ...
- Linux下U盘、SD卡挂载与卸载
1.手动挂载/卸载U盘.SD卡 对于ARM Linux来说,第一次使用U盘或SD时,U盘这个文件目录是不能直接进入的,我们需要对其进行挂载,然后再接下来的使用中就可以直接进行使用了.通过再网上查资料, ...