Spring学习(三)
DI (Dependency Injection)
1、依赖注入,组件之间的依赖关系由容器在运行期间决定。Ioc容器注入应用程序某个对象,它所需要的外部资源(包括对象,资源,常量数据)。
birthdate需要用到date类型的一个对象,引用了d的对象就是一种DI(依赖注入),s.setBirthdate( d )依赖一个date类型的对象,注入就是将date类型的对象set进去。
<bean id="d" class="java.util.Date" />
<bean id="s" class="io.spring.ioc.base.Student" >
<property name="id" value="1001" />
<property name="name" value="张三丰" />
<property name="gender" value="男" />
<property name="birthdate" ref="d" />
</bean>
相当于s.setBirthdate( d ),也可以指定内部的bean
<bean id="s" class="io.spring.ioc.base.Student">
<property name="id" value="1001" />
<property name="name" value="张三丰" />
<property name="gender" value="男" />
<property name="birthdate" >
<bean class="java.util.Date" />
</property>
</bean>
相当于s.setBirthdate( new Date )。
Spring Ioc容器
1、具有依赖注入功能的容器。负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。在Spring中BeanFactory是Ioc容器的实际代表者。BeanFactory接口提供了IoC容器的基本功能。Spring Ioc容器通过读取配置文件中的配置元数据,通过元数据对应用中各个对象进行实例化及装配。
Spring IoC容器注入依赖资源的方式
1、Spring IoC容器注入依赖资源的方式有两种setter注入和构造方法注入。
2、setter注入, ( setter-base ),提供setter方法进行注入,依赖于无参构造和setter方法
- Spring Framework 3.0 之前 ,使用property标记来来指定属性的注入值
<bean id="customer" class="ecut.ioc.di.Customer" > c.setId(1002)
<property name="id" value="1002" />
<property name="name" value="张翠山" />
<property name="gender" value="男" />
<property name="birthdate" ref="date" />
</bean>通过bean标记来声明这个bean,使用bean标记的id或name属性来指定bean的名称 , bean的class属相来指定bean的类型(具体的不是抽象的,不然需要修改abstract属性为true),name属性指定setter方法对应的名称,比如setBirthdate就写birthdate,ref属性用来指定需要引用的那个已经存在的bean的名称,普通类型用value,需要引用的类型使用ref。
- Spring Framework 3.0 开始支持 p 命名空间为属性注入值 ,也依赖于无参构造和setter方法
<!-- setter方法注入, 使用P命名空间(property namespace,需要提供p命名空间)-->
<bean id="customer"
class="ecut.ioc.di.Customer"
p:id="1002"
p:name="张翠山"
p:gender="男"
p:birthdate-ref="date" />普通类型p:name="value",需要引用的类型使用p:name-ref="引用bean的id"
- 测试案例
Customer类
package ecut.ioc.di; import java.util.Date; public class Customer { private Integer id;
private String name;
private char gender;
private Date birthdate; public Customer() {
super();
System.out.println( "调用 Customer 无参构造创建对象" );
} public Customer(Integer id, String name, char gender) {
super();
this.id = id;
this.name = name;
this.gender = gender;
System.out.println( "调用 Customer( Integer , String , char ) 创建对象" );
} public Customer(Integer id, String name, char gender, Date birthdate) {
super();
this.id = id;
this.name = name;
this.gender = gender;
this.birthdate = birthdate;
System.out.println( "调用 Customer( Integer , String , char , Date ) 创建对象" );
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
System.out.println( "为id属性赋值: " + id );
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
System.out.println( "为name属性赋值: " + name );
} public char getGender() {
return gender;
} public void setGender(char gender) {
this.gender = gender;
System.out.println( "为gender属性赋值: " + gender );
} public Date getBirthdate() {
return birthdate;
} public void setBirthdate(Date birthdate) {
this.birthdate = birthdate;
System.out.println( "为birthdate属性赋值: " + birthdate );
} }setter-injection.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> <bean id="date" class="java.util.Date" /> <!-- setter方法注入, 使用P命名空间(property namespace,需要提供p命名空间)-->
<bean id="customer"
class="ecut.ioc.di.Customer"
p:id="1002"
p:name="张翠山"
p:gender="男"
p:birthdate-ref="date" /> <!-- 通过bean标记来声明这个bean
使用bean标记的id或name属性来指定bean的名称 ,
bean的class属相来指定bean的类型(具体的不是抽象的,不然需要修改abstract属性为true),
name属性指定setter方法对应的名称,比如setBirthdate就写birthdate,
ref属性用来指定需要引用的那个已经存在的bean的名称-->
<!--Customer c = new Customer(); -->
<!--<bean id="customer" class="ecut.ioc.di.Customer" > c.setId(1002)
<property name="id" value="1002" />
<property name="name" value="张翠山" />
<property name="gender" value="男" />
<property name="birthdate" ref="date" />
</bean>
--> </beans>测试类
package ecut.ioc.di; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSetterInjection { public static void main(String[] args) {
//指定configuration metadata配置元数据
String configLocations = "classpath:ecut/**/di/setter-injection.xml" ;
//创建spring IOC容器
AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations );
//ready for use (此时可以从指定的IOC容器中获取指定名称的bean实例了)
Customer c = container.getBean( "customer" , Customer.class );
//从容器中获取的bean实例中获取属性值
System.out.println( c.getId() ); System.out.println( c.getName() ); System.out.println( c.getGender() ); System.out.println( c.getBirthdate() );
//关闭spring的IOC容器
container.close(); } }
3、构造方法注入 : ( constructor-base )通过构造方法往里面传入值
- 测试案例
constructor-injection.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> <bean id="date" class="java.util.Date" /> <!-- constructor 调用有参数的构造 -->
<bean id="customer" class="ecut.ioc.di.Customer" >
<!-- 在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,
也可以根据type匹配相应的参数如果这个类型参数唯一,
也可以指定index来指定参数,若和参数顺序一致index可以省略,
name是指参数名称,value是指定的参数值 -->
<constructor-arg name="id" type="java.lang.Integer" value="1003" />
<constructor-arg name="name" type ="java.lang.String" value="殷素素" />
<constructor-arg name="gender" value="女" />
<!-- 如果参数类型不是简单类型就需要使用ref去引用其他的bean -->
<constructor-arg name="birthdate" ref="date" />
</bean> <!-- <bean id="customer" class="ecut.ioc.di.Customer" >
在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,
也可以根据type匹配相应的参数如果这个类型参数唯一,
也可以指定index来指定参数,若和参数顺序一致index可以省略,
name是指参数名称,value是指定的参数值
<constructor-arg type="java.lang.Integer" value="1003" />
<constructor-arg type ="java.lang.String" value="殷素素" />
<constructor-arg value="女" />
<constructor-arg ref="date" />
</bean> --> <!-- constructor 调用有参数的构造 -->
<!-- <bean id="customer" class="ecut.ioc.di.Customer" >
在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,
也可以根据type匹配相应的参数如果这个类型参数唯一,
也可以指定index来指定参数,若和参数顺序一致index可以省略,
name是指参数名称,value是指定的参数值
<constructor-arg name="id" value="1003" />
<constructor-arg name="name" value="殷素素" />
<constructor-arg name="gender" value="女" />
<constructor-arg name="birthdate" ref="date" />
</bean> --> <!-- <bean id="customer" class="ecut.ioc.di.Customer" >
在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,
也可以根据type匹配相应的参数如果这个类型参数唯一,
也可以指定index来指定参数,若和参数顺序一致index可以省略,
name是指参数名称,value是指定的参数值
<constructor-arg value="1003" />
<constructor-arg value="殷素素" />
<constructor-arg value="女" />
<constructor-arg ref="date" />
</bean> --> <!-- <bean id="customer" class="ecut.ioc.di.Customer" >
在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,
也可以根据type匹配相应的参数如果这个类型参数唯一,
也可以指定index来指定参数,若和参数顺序一致index可以省略,
name是指参数名称,value是指定的参数值
<constructor-arg index="0" value="1003" />
<constructor-arg index="2" value="女" />
<constructor-arg index="1" value="殷素素" />
<constructor-arg index="3" ref="date" />
</bean> --> </beans>在bean标记内部使用constructor-arg标记来指定构造方法的参数为 ,也可以根据type匹配相应的参数如果这个类型参数唯一,也可以指定index来指定参数,若和参数顺序一致index可以省略,name是指参数名称,value是指定的参数值。
测试类
package ecut.ioc.di; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestConstructorInjection { public static void main(String[] args) {
//指定configuration metadata配置元数据
String configLocations = "classpath:ecut/**/di/constructor-injection.xml" ;
//创建spring IOC容器
AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations );
//ready for use (此时可以从指定的IOC容器中获取指定名称的bean实例了)
Customer c = container.getBean( "customer" , Customer.class );
//从容器中获取的bean实例中获取属性值
System.out.println( c.getId() ); System.out.println( c.getName() ); System.out.println( c.getGender() ); System.out.println( c.getBirthdate() );
//关闭spring的IOC容器
container.close(); } }如果在Customer类中写了带参数的构造最好写 无参构造,只写有参构造,虚拟机不会再分配无参构造, 因为没有提供无参构造会抛出异常BeanCreationException,没有找到默认构造方法 No default constructor found;
Spring IoC容器注入集合
1、Spring不仅能注入简单类型数据,还能注入集合(Collection、Set、List)类型、数组(Array)类型、字典(Map)类型数据、Properties类型数据。
2、3.0之前的注入方式:在 <property> 标签 内部 使用 set 、list 、map 、props 标签实现注入: normal-injection.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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> <bean id="birthdate" class="java.util.Date" /> <bean id="findFriend" class="java.util.Date" /> <bean id="user" class="ecut.ioc.collection.User">
<property name="id" value="1001" />
<property name="name" value="张三丰" /> <!-- 注入 Set 集合 -->
<property name="hobby">
<set>
<value>吃饭</value>
<value>睡觉</value>
<value>泡妞/被泡</value>
</set>
</property> <!-- 注入 List 集合 -->
<property name="luckDay">
<list>
<!-- 如果不是基本数据类型及其包装类型,通过ref 来引用-->
<ref bean="birthdate"/>
<ref bean="findFriend"/>
</list>
</property> <!-- 注入 Map 集合 -->
<property name="score">
<map>
<entry key="前端" value="45" />
<entry key="后端" value="54" />
</map>
</property> <!-- 注入 Properties 集合 -->
<property name="address">
<props>
<prop key="软件楼">东理北门内,太谷路旁,软件楼一楼厕所边的那个门</prop>
<prop key="宿舍">东理南区研一好望角</prop>
</props>
</property> </bean> </beans>
3、3.0全新的注入方式:使用 Spring 3.0 开始提供的 util 命名空间,结合 <property> 或 p 命名空间实现注入: util-injection.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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <bean id="birthdate" class="java.util.Date" /> <bean id="findFriend" class="java.util.Date" /> <util:set id="hobby" set-class="java.util.HashSet">
<value>吃饭</value>
<value>睡觉</value>
<value>泡妞/被泡</value>
</util:set> <util:list id="luckDay" list-class="java.util.ArrayList">
<ref bean="birthdate" />
<ref bean="findFriend" />
</util:list> <util:map id="score" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.Integer">
<entry key="前端" value="45" />
<entry key="后端" value="54" />
</util:map> <util:properties id="address">
<prop key="软件楼">东理北门内,太谷路旁,软件楼一楼厕所边的那个门</prop>
<prop key="宿舍">东理南区研一好望角</prop>
</util:properties> <!-- <bean id="user" class="io.spring.ioc.collection.User" p:address-ref="address"> -->
<bean id="user" class="ecut.ioc.collection.User" >
<property name="id" value="1001" />
<property name="name" value="张三丰" /> <!-- 注入 Set 集合 -->
<property name="hobby" ref="hobby"/> <!-- 注入 List 集合 -->
<property name="luckDay" ref="luckDay" /> <!-- 注入 Map 集合 -->
<property name="score" ref="score"/> <!-- 注入 Properties 集合 -->
<property name="address" ref="address"/> </bean> </beans>
转载请于明显处标明出处
https://www.cnblogs.com/AmyZheng/p/9249548.html
Spring学习(三)的更多相关文章
- spring学习(三) ———— spring事务操作
前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...
- Spring学习三
Spring注解来注入bean 在classpath中扫描组件 组件扫描,即componetscanning 利用注解来扫描的组件有 @Component :基本注解,表示一个受Spring管理的 ...
- Spring学习(三)--高级装配
一.Spring profile 在开发软件的时候,有一个很大的挑战就是将应用程序从一个环境迁 移到另外一个环境.开发阶段中,某些环境相关做法可能并不适合迁 移到生产环境中,甚至即便迁移过去也无法正常 ...
- spring学习 三 框架的搭建
1 导入jar包 spring启来最少要5个包,四个核心包和一个依赖的日志包 2 创建配置文件 在dynamic web project下的src目录下,创建一个spring的xml配置文件,名称可以 ...
- Spring学习(三)-----Spring自动装配Beans
在Spring框架,可以用 auto-wiring 功能会自动装配Bean.要启用它,只需要在 <bean>定义“autowire”属性. <bean id="custom ...
- Spring学习三----------注入方式
© 版权声明:本文为博主原创文章,转载请注明出处 Spring注入方式 本篇博客只讲最常用的两种注入方式:设值注入和构造器注入.代码为完整代码,复制即可使用. 1.目录结构 2.pom.xml < ...
- spring学习三:Spring Bean 生命周期
Bean 的生命周期 理解 Spring bean 的生命周期很容易.当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态.同样,当 bean 不再需要,并且从容器中移除时,可能需 ...
- spring学习三:Spring的Aop、代理
ref:https://mp.weixin.qq.com/s/J77asUvw8FcnF-6YlX6AAw AOP相关术语: Joinpoint(连接点):类里面可以被增强的方法,这些方法称为连 ...
- Spring学习(六)-----Spring使用@Autowired注解自动装配
Spring使用@Autowired注解自动装配 在上一篇 Spring学习(三)-----Spring自动装配Beans示例中,它会匹配当前Spring容器任何bean的属性自动装配.在大多数情况下 ...
随机推荐
- 数星星 Stars
问题 A: 数星星 Stars 时间限制: 1 Sec 内存限制: 128 MB[命题人:admin] 题目描述 输入 第一行一个整数 N,表示星星的数目: 接下来 N 行给出每颗星星的坐标,坐标用 ...
- Docker - 命令 - docker network
概述 docker network 命令 背景 newwork 是 docker 的一种资源 经常会使用 需要整理命令 1. 引入 概述 docker run 时, 将容器端口映射到宿主机 场景 启动 ...
- IDE - IDEA - 快捷键整理 - 01. Navigation
1. 概述 工具的熟练程度, 会决定工作效率 总共也就 140 条左右吧 需要讲解吗? 2. ref 1. idea 自带的 ReferenceCard.pdf 3. keymap 1. 文件移动 C ...
- 作业1:使用go搭建一个web-server
todo1:搭建web-server的原理 todo2:go实现web-server
- mysql中的文件排序(filesort)
在MySQL中的ORDER BY有两种排序实现方式: 1. 利用有序索引获取有序数据 2. 文件排序 在explain中分析查询的时候,利用有序索引获取有序数据显示Using index ,文件排序显 ...
- uni-app 去除顶部导航栏
自学uni-app第一天,因为有一点点的小程序和vue的基础所以感觉对uni-app有一点点的亲切感,从今天呢开始着手从登录页学习uni-app,记录一些用到的知识点,欢迎大家一起学习. 启动页隐藏顶 ...
- idea项目更改git地址
第一步:idea打开项目,菜单栏找VCS - Git - Remotes 点进去,弹出对话框,选中,点击编辑 弹出编辑框,更改地址,点击ok 弹出输入账号密码编辑框,输入自己的账号密码,点击确认 完成 ...
- vue使用过程中遇到的细节问题
1. 在methods 中添加一个方法.如果这个方法使用箭头函数的话,箭头函数中的this不是当前的vue实例,所以通过this.xxx是获取不到实例上面的属性的,这时我们可以用函数的简写来获取到实例 ...
- 安装nodejs时提示Leaving directory
在按照标准的编译命令./configure =>make =>make install 在make的时候发生错误: ../deps/v8/src/base/platform/mutex.h ...
- 「CSP-S模拟赛」2019第二场
目录 T1 Jam的计数法 题目 考场思路(正解) T2 「TJOI / HEOI2016」排序 题目 考场思路(假正解) 正解 T3 「THUWC 2017」随机二分图 题目 考场思路 正解 这场考 ...