spring的注入bean的几种方式

2023-11-06

平常的Java开发中,程序员在某个类中需要依赖其它类的方法。
通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理。
Spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过Spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。
依赖注入的另一种说法是”控制反转”。通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员。

而控制反转是指new实例工作不由我们程序员来做而是交给Spring容器来做。

Spring有多种依赖注入的形式,本篇文章仅介绍Spring通过xml进行IOC配置的方式。

1.Set注入

这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口):

package com.bless.springdemo.action; 
public class SpringAction { 
    //注入对象springDao 
    private SpringDao springDao; 
    //一定要写被注入对象的set方法 
    public void setSpringDao(SpringDao springDao) { 
    this.springDao = springDao; 
} 

public void ok(){ 
    springDao.ok(); 
} 
}

随后编写spring的xml文件,中的name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在标签中创建一个标签指定SpringDao。标签中的name就是SpringAction类中的SpringDao属性名,ref指下面,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction"> 
<!--(1)依赖注入,配置当前类中相应的属性--> 
<property name="springDao" ref="springDao"></property> 
</bean> 
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>

2.构造器注入

这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:

public class SpringAction { 
    //注入对象springDao 
    private SpringDao springDao; 
    private User user; 

    public SpringAction(SpringDao springDao,User user){ 
    this.springDao = springDao; 
    this.user = user; 
    System.out.println("构造方法调用springDao和user"); 
} 

public void save(){ 
    user.setName("卡卡"); 
    springDao.save(user); 
} 
} 

在XML文件中同样不用的形式,而是使用标签,ref属性同样指向其它标签的name属性:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction"> 
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置--> 
<constructor-arg ref="springDao"></constructor-arg> 
<constructor-arg ref="user"></constructor-arg> 
</bean> 
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean> 
<bean name="user" class="com.bless.springdemo.vo.User"></bean> 

解决构造方法参数的不确定性,你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理:

下面是设置index,就是参数位置:

<bean name="springAction" class="com.bless.springdemo.action.SpringAction"> 
<constructor-arg index="0" ref="springDao"></constructor-arg> 
<constructor-arg index="1" ref="user"></constructor-arg> 
</bean> 

另一种是设置参数类型:

<constructor-arg type="java.lang.String" ref=""/>

3.静态工厂的方法注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过”工程类.静态方法()”来获取对象,而是依然通过spring注入的形式获取:

package com.bless.springdemo.factory; 

import com.bless.springdemo.dao.FactoryDao; 
import com.bless.springdemo.dao.impl.FactoryDaoImpl; 
import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl; 

public class DaoFactory { 
//静态工厂 
public static final FactoryDao getStaticFactoryDaoImpl(){ 
    return new StaticFacotryDaoImpl(); 
    } 
}

同样看关键类,这里我需要注入一个FactoryDao对象,这里看起来跟第一种注入一模一样,但是看随后的xml会发现有很大差别:

public class SpringAction { 
//注入对象 
private FactoryDao staticFactoryDao; 

public void staticFactoryOk(){ 
    staticFactoryDao.saveFactory(); 
} 
//注入对象的set方法 
public void setStaticFactoryDao(FactoryDao staticFactoryDao) { 
    this.staticFactoryDao = staticFactoryDao; 
} 
} 

Spring的IOC配置文件,注意看指向的class并不是FactoryDao的实现类,而是指向静态工厂DaoFactory,并且配置 factory-method=”getStaticFactoryDaoImpl”指定调用哪个工厂方法:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction" > 
<!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)--> 
<property name="staticFactoryDao" ref="staticFactoryDao"></property> 
</property> 
</bean> 
<!--(3)此处获取对象的方式是从工厂类中获取静态方法--> 
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean> 

4.实例工厂的方法注入

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法:

public class DaoFactory { 
//实例工厂 
public FactoryDao getFactoryDaoImpl(){ 
    return new FactoryDaoImpl(); 
} 
}

那么下面这个类没什么说的,跟前面也很相似,但是我们需要通过实例工厂类创建FactoryDao对象:

public class SpringAction { 
//注入对象 
private FactoryDao factoryDao; 

public void factoryOk(){ 
    factoryDao.saveFactory(); 
} 

public void setFactoryDao(FactoryDao factoryDao) { 
    this.factoryDao = factoryDao; 
    } 
} 

最后看spring配置文件:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction"> 
<!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)--> 
<property name="factoryDao" ref="factoryDao"></property> 
</bean> 


<!--(4)此处获取对象的方式是从工厂类中获取实例方法--> 
<bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean> 
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean> 

5.总结

Spring IOC注入方式用得最多的是(1)(2)种,多写多练就会非常熟练。

另外注意:通过Spring创建的对象默认是单例的,如果需要创建多实例对象可以在标签后面添加一个属性:

<bean name="..." class="..." scope="prototype">

转自:http://blessht.iteye.com/blog/1162131

参考理解的文章:

1、Spring定义bean的三种方式和自动注入
2、 spring bean注入的方式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring的注入bean的几种方式 的相关文章

  • 如何在 JPA 中使用枚举

    我有一个电影租赁系统的现有数据库 每部电影都有一个评级属性 在 SQL 中 他们使用约束来限制该属性的允许值 CONSTRAINT film rating check CHECK rating text text OR rating tex
  • 哪个类调用了我的静态方法?

    假设我有一个带有静态方法的 Java 类 如下所示 class A static void foo Which class invoked me 进一步假设 A 类有任意数量的子类 class B extends A class C ext
  • Eclipse 自动完成更改变量名称

    只是一个愚蠢的问题 但很难搜索 因为有很多关于 Eclipse 自动完成的主题 而且很难找到与我的问题匹配的内容 所以问题是 如果我写 MyClass MyVarName 然后按空格键 添加 new MyClass Eclipse 自动添加
  • 将 JSON Map 传递到 Spring MVC 控制器

    我正在尝试将 Map 的 JSON 表示形式作为 POST 参数发送到我的控制器中 RequestMapping value search do method RequestMethod GET consumes application j
  • 我需要显式关闭连接吗?

    我持有一个实例MongoClient and DB在我的应用程序中 每次我想执行某些操作时 我都会调用getCollection 我想知道是否需要显式关闭连接 就像connection close 在 JDBC 中 强调一下 我只有一个Mo
  • 确定代码是否在 App Engine 运行时 (Java) 上运行

    如何确定某些代码 Serv let 或简单的类 是否正在 Google App Engine 运行时 Java 上运行 以便决定是否使用 App Engine 的特定库 是否有一些可靠的运行时环境 ID 您可以检查com google ap
  • Spring 术语中命令、表单、业务和实体对象之间的区别?

    我试图理解这些对象在松散耦合系统方面的差异 业务对象与实体对象相同吗 我可以使用 MVC 中的业务或实体对象作为我的命令对象吗 命令对象与表单对象相同吗 只是寻找 Spring 术语和用法中对象类型的说明 我在 stackoverflow
  • java.lang.UnsupportedOperationException:无法解析索引 13 处的属性:TypedValue{t=0x2/d=0x7f010046 a=-1}

    我在 android attrs xml 文件中添加了一个用于不同色调的属性 在 styles xml 文件中 我为这些属性指定了颜色 因此每种样式的它们都不同 Attrs xml
  • 驱动程序信息:driver.version:未知,使用 ChromeDriver v78.0.3904.70 和 Chrome 浏览器 v78.0.3904.97

    我使用的是java 1 8和chrome浏览器版本78 0 3904 97 我正在尝试使用 chrome 驱动程序版本执行我的 selenium 脚本代码78 0 3904 70 但在执行时我面临以下问题并且 chrome 立即崩溃 Pic
  • 设置 JAVA_HOME 变量时出现问题

    所以我刚刚下载了 Android Studio 并尝试设置 JAVA HOME 变量以便我可以运行它 我使用的是 Windows 8 并按照我找到的所有说明进行操作 但无济于事 转到高级系统设置 gt 环境变量 然后使用包含我的 jre7
  • 处理照片上传的最佳方式是什么?

    我正在为一个家庭成员的婚礼制作一个网站 他们要求的一个功能是一个照片部分 所有客人都可以在婚礼结束后前往并上传他们的照片 我说这是一个很棒的想法 然后我就去实现它 那么只有一个问题 物流 上传速度很慢 现代相机拍摄的照片很大 2 5 兆 我
  • 链表中的虚拟节点

    问 什么时候使用它们 作业问题 列表中的第一个和最后一个节点 有时用作列表中的第一个和最后一个节点 从未用作列表中的第一个和最后一个节点 维基百科说 哨兵节点是与链接一起使用的专门指定的节点 列表和树作为遍历路径终止符 哨兵节点的作用是 不
  • Java .split("|") 不工作

    我刚刚遇到了一个问题分割法 http docs oracle com javase 6 docs api java lang String html split 28java lang String 29for 字符串不适用于字符 作为一个
  • Storm Spout 未收到 Ack

    我已经开始使用storm 所以我使用创建简单的拓扑本教程 https github com nathanmarz storm wiki Tutorial 当我运行我的拓扑时LocalCluster一切看起来都很好 我的问题是我没有得到元组的
  • Microsoft JDBC 中的 JTDS 属性相当于什么?

    我正在将 JTDS 连接更改为 Microsoft JDBC 并且我看到存在于http jtds sourceforge net faq html http jtds sourceforge net faq htmlMicrosoft JD
  • Checkstyle - 方法按修饰符排序

    是否可以添加到 checkstyle 规则以按修饰符对类中的方法进行排序 我的意思是开头的公共方法和最后的私有方法 MethodsOrderCheck做这个工作 检查文档 https www qulice com qulice checks
  • Java 相当于 Python 的 urllib.urlencode(基于 HashMap 的 UrlEncode)

    From https stackoverflow com questions 2018026 should i use urllib or urllib2 2018103 2018103 Java 中 Python 的 urllib url
  • Python 可以替代 Java 小程序吗?

    除了制作用于物理模拟 如抛射运动 重力等 的教育性 Java 小程序之外 还有其他选择吗 如果你想让它在浏览器中运行 你可以使用PyJamas http pyjs org 这是一个 Python 到 Javascript 的编译器和工具集
  • 将带有时区的 Joda-Time `DateTime` 转换为没有时区的 DateTime?

    Given a DateTime http www joda org joda time apidocs org joda time DateTime html例如2015 07 09T05 10 00 02 00 using 乔达时间 h
  • 升级到 Tomcat 8 时出现 ClassNotFoundException

    我最近将 NetBeans IDE 从 v7 3 升级到 v8 突然我的应用程序在连接到数据库时在服务器启动时抛出异常 这两个版本的 IDE 之间的唯一区别是后者使用 Tomcat 8 异常日志 javax naming NamingExc

随机推荐

  • LDA模型训练与得到文本主题、困惑度计算(含可运行案例)

    文章目录 模块一 训练LDA模型 模块二 困惑度计算 模块三 得到一段文本的主题 全部代码及案例 可直接运行 首先使用gensim库 pip install gensim 模块一 训练LDA模型 import gensim pip inst
  • 07-微信小程序-注册页面-模块化

    07 微信小程序 注册页面 文章目录 注册页面 使用 Page 构造器注册页面 参数Object 初始数据 案例代码 生命周期回调函数 组件事件处理函数 setData 案例代码 生命周期 模块化 注册页面 对于小程序中的每个页面 都需要在
  • [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形

    欢迎大家来到 Python从零到壹 在这里我将分享约200篇Python系列文章 带大家一起去学习和玩耍 看看Python这个有趣的世界 所有文章都将结合案例 代码和作者的经验讲解 真心想把自己近十年的编程经验分享给大家 希望对您有所帮助
  • HTML CSS 盒模型 +background 使用

    HTML 盒模型 box model 和background 部分内容来自菜鸟教程 所有HTML元素可以看作盒子 在CSS中 box model 这一术语是用来设计和布局时使用 CSS盒模型本质上是一个盒子 封装周围的HTML元素 它包括
  • 写一个函数,用户输入一个数判断是否是素数

    写一个函数 用户输入一个数判断是否是素数 function get num if num 1 num 0 return num 不是质数 for var i 2 i lt num i if num i 0 return num 不是质数 r
  • oracle生成标准uuid,Oracle 生成uuid方法

    近日 遇到朋友问及如何生成UUID 是 通用唯一识别码 Universally Unique Identifier 方法 其实数据中是支持的 Oracle中生成跨系统的唯一识别符UUID非常方便 比生成序列还简单 直接用sys guid 就
  • Stable Doodle:简单涂鸦一键变成艺术品

    摘要 Stable Doodle 是一款使用 AI 技术将简单涂鸦转化为艺术品的应用 它可以帮助用户快速 轻松地创作出精美的图画 本教程将介绍 Stable Doodle 的基本使用方法 正文 Stable Doodle 的使用非常简单 只
  • 2080ti,驱动安装,CUDA安装,CUDNN安装,CUDA10.1的不兼容问题

    发现问题 哎呦 我跑的是CPU 不是GPU 解决问题 Tensorflow目前不支持CUDA10 1 继续解决问题 哎呦 驱动被不小心删掉了 那就全部重新安装吧 最终解决好了 跑起来了 看似GPU 其实跑的是CPU 之前写了代码发现 能跑起
  • 分布式版本控制VS集中式版本控制

    集中式版本控制 诸如CVS SVN等 都有一个集中管理的服务器 保存所有的文件修订版本 而协同工作的人们都通过客户端连接到这台服务器 取出最新的文件或者提交更新 如上图所示 A B C为三位开发者 这是A将代码拉到本地进行开发 这个时候A开
  • raise_for_status()方法

    raise for status 方法 理解Response类非常重要 Response这样的一个对象返回了所有的网页内容 那么它也提供了一个方法 叫raise for status 这个方法是专门与异常打交道的方法 该方法有这样一个有趣的
  • 如何模拟弱网条件 - 限流, 丢包, 延迟和抖动

    Abstract 弱网条件的模拟 Authors Walter Fan Category learning note Status v1 0 Updated 2023 02 16 License CC BY NC ND 4 0 概述 在网络
  • 什么是车联网

    要弄清车联网是什么 还要从许多年前说起 比尔 盖茨等人曾提出物联网的概念 即 万物相连的互联网 物联网是要将各种信息传感设备与互联网结合起来从而形成一个的巨大的网络 简单来说 就是给各种各样的事物连上互联网 然后人们可以通过某个设备远程监控
  • 如何高效定位网络丢包问题?

    引言 本期分享一个比较常见的网络问题 丢包 例如我们去ping一个网站 如果能ping通 且网站返回信息全面 则说明与网站服务器的通信是畅通的 如果ping不通 或者网站返回的信息不全等 则很可能是数据被丢包了 类似情况想必大家都不陌生 针
  • java后端使用websocket实现与客户端之间接收及发送消息

    客户端请求websocket接口 连接通道 我这边业务成功客户端发消息 客户端自动刷新 接口 ws localhost 8080 websocket xx import org springframework web socket conf
  • Docker 安装 ES eslasticsearch

    Docker 安装 ES eslasticsearch 1 下载镜像 我这里下载的是 6 8 14 如果你不知道有哪些版本 可以查看 https hub docker com elasticsearch root localhost jzj
  • Java线程池多线程查询数据库提高查询效率

    Java线程池多线程查询数据库提高查询效率 需求 问题 思路 代码 解析 需求 公司数据统计报表查询 几张大表关联查询 包含跨库查询 数据联查 数据过滤 数据统计 问题 主表数据1 主表数据2 统计数据1 统计数据2 数据 数据 数据 数据
  • Linux_centos安装后无法进入图形界面

    问题 直接默认进入字符界面 root之后init 5也没用 解决方法 出现问题的原因在于安装时选择了最小安装 如图所示 转载于 https www cnblogs com vocoub p 11537978 html
  • OpenHarmony 3.1Release 电话功能演示—基于润和DAYU200开发套件

    1 前言 令人期待的OpenHarmony 3 1Release终于在3月31号发布了 目前DAYU200是首款支持OpenHarmony 3 1 Release版本的开发套件 官方购买链接购买 淘宝 https item taobao c
  • mac安装lrzsz出错Command failed with exit 128: git

    终端检查电脑是否安装了rz和sz which sz 若报错 则需要下载 由于网络和代理的原因 以下命令会报错 brew install lrzsz 是因为brew和git配置的代理存在冲突 对于无外网链接功能 无特殊配置的git而言 需要安
  • spring的注入bean的几种方式

    平常的Java开发中 程序员在某个类中需要依赖其它类的方法 通常是new一个依赖类再调用类实例的方法 这种开发存在的问题是new的类实例不好统一管理 Spring提出了依赖注入的思想 即依赖类不由程序员实例化 而是通过Spring容器帮我们