09 Spring的依赖注入
1.依赖注入(Dependency Injection)
(1)IOC的作用:
降低程序间的耦合(依赖关系)
(2)依赖关系的管理:
以后都交给spring来维护
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
(3)依赖关系的维护:
就称之为依赖注入。
依赖注入:
能注入的数据类型:基本类型和String、其他bean类型(在配置文件中或者注解配置过的bean)、复杂类型/集合类型。
注入的方式:有三种
第一种:使用构造函数提供
第二种:使用set方法提供
第三种:使用注解提供
(4)应用案例搭建
<1>业务层的接口:IAccountService.java
- package service;
- /**
- * 账户业务层的接口
- */
- public interface IAccountService {
- /**
- * 模拟保存账户
- */
- void saveAccount();
- }
<2>业务层的接口实现类:AccountServiceImpl.java
- package service.impl;
- import service.IAccountService;
- import java.util.Date;
- /**
- * 账户的业务层实现类
- */
- public class AccountServiceImpl implements IAccountService {
- //如果是经常变化的数据,并不适用于注入的方式
- private String name;
- private Integer age;
- private Date birthday;
- public AccountServiceImpl(String name,Integer age,Date birthday){
- this.name = name;
- this.age = age;
- this.birthday = birthday;
- }
- public AccountServiceImpl(){
- System.out.println("对象创建了");
- }
- public void saveAccount(){
- System.out.println("AccountServiceImpl中的saveAccount方法执行了"+name+","+age+","+birthday);
- }
- }
<3>表现层
- package ui;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import service.IAccountService;
- import service.impl.AccountServiceImpl;
- /**
- * 模拟一个表现层,用于调用业务层
- */
- public class Client {
- /**
- * 获取spring的Ioc核心容器,并根据id获取对象
- *
- * ApplicationContext的三个常用实现类:
- * ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用)
- * FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
- *
- * AnnotationConfigApplicationContext:它是用于读取注解创建容器的,是明天的内容。
- *
- * 核心容器的两个接口引发出的问题:
- * ApplicationContext: 单例对象适用 采用此接口
- * 它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
- *
- * BeanFactory: 多例对象使用
- * 它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
- * @param args
- */
- public static void main(String[] args) {
- //1.获取核心容器对象
- ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
- //2.根据id获取Bean对象,注意id是在bean.xml文件配置的
- IAccountService as = (IAccountService)ac.getBean("accountService");
- as.saveAccount();
- }
- }
(5)依赖注入
<1>使用构造函数注入(尽量不使用)
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
name:用于指定给构造函数中指定名称的参数赋值 常用的
=============以上三个用于指定给构造函数中哪个参数赋值===============================
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的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">
- <!--构造函数注入:
- 使用的标签:constructor-arg
- 标签出现的位置:bean标签的内部
- 标签中的属性
- type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
- index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
- name:用于指定给构造函数中指定名称的参数赋值 常用的
- =============以上三个用于指定给构造函数中哪个参数赋值===============================
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
- 优势:
- 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
- 弊端:
- 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
- -->
- <bean id="accountService" class="service.impl.AccountServiceImpl" scope="prototype">
- <constructor-arg name="name" value="泰斯特"></constructor-arg>
- <constructor-arg name="age" value="18"></constructor-arg>
- <constructor-arg name="birthday" ref="now"></constructor-arg>
- </bean>
- <!-- 配置一个日期对象 -->
- <bean id="now" class="java.util.Date"></bean>
- </beans>
<2>set方法注入(最常用的方式)
涉及的标签:property
出现的位置:bean标签的内部
标签的属性
name:用于指定注入时所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:
创建对象时没有明确的限制,可以直接使用默认构造函数
弊端:
如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
(1)普通数据类型的注入:
业务层的接口实现类:AccountServiceImpl2.java
- package service.impl;
- import service.IAccountService;
- import java.util.Date;
- /**
- * 账户的业务层实现类
- */
- public class AccountServiceImpl2 implements IAccountService {
- //如果是经常变化的数据,并不适用于注入的方式
- private String name;
- private Integer age;
- private Date birthday;
- public void setName(String name) {
- this.name = name;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- public AccountServiceImpl2(){
- System.out.println("对象创建了");
- }
- public void saveAccount(){
- System.out.println("AccountServiceImpl中的saveAccount方法执行了"+name+","+age+","+birthday);
- }
- }
bean.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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-- 配置一个日期对象 -->
- <bean id="now" class="java.util.Date"></bean>
- <!-- set方法注入 更常用的方式
- 涉及的标签:property
- 出现的位置:bean标签的内部
- 标签的属性
- name:用于指定注入时所调用的set方法名称
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
- 优势:
- 创建对象时没有明确的限制,可以直接使用默认构造函数
- 弊端:
- 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
- -->
- <bean id="accountService2" class="service.impl.AccountServiceImpl2">
- <property name="name" value="TEST" ></property>
- <property name="age" value="21"></property>
- <property name="birthday" ref="now"></property>
- </bean>
- </beans>
(2)复杂类型数据的注入:
复杂类型的注入/集合类型的注入
(1)用于给List结构集合注入的标签:
list array set
(2)用于个Map结构集合注入的标签:
map props
结构相同,标签可以互换
业务层的接口实现类:AccountServiceImpl3.java
- package service.impl;
- import service.IAccountService;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Properties;
- import java.util.Set;
- import java.util.Map;
- /**
- * 账户的业务层实现类
- */
- public class AccountServiceImpl3 implements IAccountService {
- private String[] myStrs;
- private List<String> myList;
- private Set<String> mySet;
- private Map<String,String> myMap;
- private Properties myProps;
- public void setMyStrs(String[] myStrs) {
- this.myStrs = myStrs;
- }
- 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 setMyProps(Properties myProps) {
- this.myProps = myProps;
- }
- public void saveAccount(){
- System.out.println(Arrays.toString(myStrs));
- System.out.println(myList);
- System.out.println(mySet);
- System.out.println(myMap);
- System.out.println(myProps);
- }
- }
bean.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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!--构造函数注入:
- 使用的标签:constructor-arg
- 标签出现的位置:bean标签的内部
- 标签中的属性
- type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
- index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
- name:用于指定给构造函数中指定名称的参数赋值 常用的
- =============以上三个用于指定给构造函数中哪个参数赋值===============================
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
- 优势:
- 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
- 弊端:
- 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
- -->
- <bean id="accountService" class="service.impl.AccountServiceImpl" scope="prototype">
- <constructor-arg name="name" value="泰斯特"></constructor-arg>
- <constructor-arg name="age" value="18"></constructor-arg>
- <constructor-arg name="birthday" ref="now"></constructor-arg>
- </bean>
- <!-- 配置一个日期对象 -->
- <bean id="now" class="java.util.Date"></bean>
- <!-- 复杂类型的注入/集合类型的注入
- 用于给List结构集合注入的标签:
- list array set
- 用于个Map结构集合注入的标签:
- map props
- 结构相同,标签可以互换
- -->
- <bean id="accountService3" class="service.impl.AccountServiceImpl3">
- <property name="myStrs">
- <set>
- <value>AAA</value>
- <value>BBB</value>
- <value>CCC</value>
- </set>
- </property>
- <property name="myList">
- <array>
- <value>AAA</value>
- <value>BBB</value>
- <value>CCC</value>
- </array>
- </property>
- <property name="mySet">
- <list>
- <value>AAA</value>
- <value>BBB</value>
- <value>CCC</value>
- </list>
- </property>
- <property name="myMap">
- <props>
- <prop key="testC">ccc</prop>
- <prop key="testD">ddd</prop>
- </props>
- </property>
- <property name="myProps">
- <map>
- <entry key="testA" value="aaa"></entry>
- <entry key="testB">
- <value>BBB</value>
- </entry>
- </map>
- </property>
- </bean>
- </beans>
表现层代码:
- package ui;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import service.IAccountService;
- import service.impl.AccountServiceImpl;
- /**
- * 模拟一个表现层,用于调用业务层
- */
- public class Client {
- /**
- * 获取spring的Ioc核心容器,并根据id获取对象
- *
- * ApplicationContext的三个常用实现类:
- * ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用)
- * FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
- *
- * AnnotationConfigApplicationContext:它是用于读取注解创建容器的,是明天的内容。
- *
- * 核心容器的两个接口引发出的问题:
- * ApplicationContext: 单例对象适用 采用此接口
- * 它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
- *
- * BeanFactory: 多例对象使用
- * 它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
- * @param args
- */
- public static void main(String[] args) {
- //1.获取核心容器对象
- ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
- //2.根据id获取Bean对象,注意id是在bean.xml文件配置的
- IAccountService as = (IAccountService)ac.getBean("accountService3");
- as.saveAccount();
- }
- }
控制台输出:
09 Spring的依赖注入的更多相关文章
- (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)
Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...
- Spring的依赖注入(DI)三种方式
Spring依赖注入(DI)的三种方式,分别为: 1. 接口注入 2. Setter方法注入 3. 构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个 ...
- spring的依赖注入的最常见的两种方法
package com.lsz.spring.action; public class User { /** * set注入 */ private String username; public vo ...
- 一步一步深入spring(3)--spring的依赖注入方式
对于spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的依赖注入就是通过spring将bean所需要的一些参数传递到bean实例对象的过程,sprin ...
- spring的依赖注入是什么意思
最近学习spring框架,对依赖注入有些模糊,遂上网翻阅资料,做了下列总结,原博客为CSDN 南夏的 spring的依赖注入是什么意思,侵删! Spring 能有效地组织J2EE应用各层的对象.不管是 ...
- SpringBoot系列: 理解 Spring 的依赖注入(一)
==============================Spring 的依赖注入==============================对于 Spring 程序, Spring 框架为我们提供 ...
- Spring.NET依赖注入框架学习--实例化容器常用方法
Spring.NET依赖注入框架学习---实例化容器常用方法 本篇学习实例化Spring.NET容器的俩种方式 1.通过XmlObjectFactory创建一个Spring.NET容器 IResour ...
- Spring.NET依赖注入框架学习--简单对象注入
Spring.NET依赖注入框架学习--简单对象注入 在前面的俩篇中讲解了依赖注入的概念以及Spring.NET框架的核心模块介绍,今天就要看看怎么来使用Spring.NET实现一个简单的对象注入 常 ...
- Spring.NET依赖注入框架学习--简介
Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...
随机推荐
- [转]windows10下安装与激活rational rose 2003
Rational Rose2003安装+激活教程(Win10)(另附安装包+激活软件) 原文链接:https://blog.csdn.net/qq_38388811/article/details/8 ...
- 小a的学期 (组合数取模模板)
题目描述 小a是一个健忘的人,由于他经常忘记做作业,因此老师对他很恼火. 小a马上就要开学了,他学期一共2n 天,对于第i天,他有可能写了作业,也可能没写作业,不过他自己心里还有点B数,因此他会写恰好 ...
- if语句的嵌套:从键盘输入3个实数,求其最大值。
#include<stdio.h>void main(){ float a,b,c,max; scanf("%f%f%f",&a,&b,&c); ...
- GoCN每日新闻(2019-10-12)
GoCN每日新闻(2019-10-12) 1. Go 1.13中sync.Pool是如何优化的 https://colobu.com/2019/10/08/how-is-sync-Pool-impro ...
- allure-pytest 测试报告分享给大家
allure-pytest生成测试报告,经过实践得出如下经验,参考了很多大神的博客一并附上 1.安装allure-pytest pip install allure-pytest 2.执行命令生成js ...
- ICEM-三角形特征几何
原视频下载地址:https://pan.baidu.com/s/1qY8SKri 密码: wf17
- ubuntu之路——day16 只用python的numpy在底层检验神经网络的优化算法
首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...
- Vintage、滚动率、迁移率的应用
python信用评分卡建模(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_ca ...
- Qt QSplitter任意拆分窗口
Qt拆分窗口可以使用QSplitter,也可以使用比较容易使用布局控件来完成,本文章给出使用QSplitter分割窗口的例子. QSplitter 继承自QFrame,而QFrame又继承自QWidg ...
- ARM USB 通信(转)
ARM USB 通信 采用ZLG的动态链接库,动态装载. ARM是Context-M3-1343. 在C++ Builder 6 中开发的上位机通信软件. USB通信代码如下: //--------- ...