Spring学习笔记--自动装配Bean属性

Spring提供了四种类型的自动装配策略:

  • byName – 把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中。
  • byType – 把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。
  • constructor – 把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean的对应属性中。
  • autodetect – 首先使用costructor进行自动装配。如果失败,再尝试使用byType进行自动装配。

我这里以关羽和青龙偃月刀为例: 首先定义一个武器接口Weapon:

package com.moonlit.myspring;public interface Weapon {public void attack();
}

然后定义一个Weapon接口的实现Falchion类:

package com.moonlit.myspring;public class Falchion implements Weapon {public void attack() {System.out.println("falcon is attacking!");}
}

定义一个英雄接口Hero:

package com.moonlit.myspring;public interface Hero {public void perform();
}

然后定义一个Hero接口的实现Guanyu类(代表关羽):

package com.moonlit.myspring;public class GuanYu implements Hero {private Weapon weapon;public void perform() {System.out.println("GuanYu pick up his weapon.");weapon.attack();}public Weapon getWeapon() {return weapon;}public void setWeapon(Weapon weapon) {this.weapon = weapon;}
}

在不涉及自动装配的情况下,我们想要通过Spring的DI将Fachion类对象注入到Guanyu类的weapon属性中,可以新建一个xml文件(我这里取名为spring-idol.xml)并在里面填写:

spring-idol.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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="falchion" class="com.moonlit.myspring.Falchion" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu"><property name="weapon" ref="falchion" /></bean></beans>

其中最主要的内容就是两个bean的声明部分:

  <bean id="falchion" class="com.moonlit.myspring.Falchion" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu"><property name="weapon" ref="falchion" /></bean>

第一个bean标签定义了一个Falchion类型的bean,第二个bean标签中将第一个bean作为weapon的值装配到了weapon属性中。 然后我们可以写一个测试程序来查看效果:

package com.moonlit.practice;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.moonlit.myspring.Hero;public class AutowirePractice {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-idol.xml");Hero guanyu = (Hero) context.getBean("guanyu");guanyu.perform();}
}

输出结果如下:

GuanYu pick up his weapon.
falcon is attacking!

到目前为止还没有涉及到自动装配的内容,接下来开始讲述自动装配的内容。

byName自动装配

改变spring-idol.xml中bean声明内容的形式如下:

  <bean id="weapon" class="com.moonlit.myspring.Falchion" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="byName" />

得到一样的结果。

我们将Falchion类的id去了一个和Guanyu类的属性weapon一样的名字,并且在guanyu bean中添加了autowire="byName"用于指明装配类型是byName自动装配。这个时候guanyu bean就是在上下文中找名为weapon的bean装配到他自己的weapon属性中。

byType自动装配

改变spring-idol.xml中bean声明内容的形式如下:

  <bean id="falchion" class="com.moonlit.myspring.Falchion" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="byType" />

得到一样的结果。

这里我们已经不用关注Falchion类对应的bean的id是什么了,因为我们已经定义guanyu bean的autowire属性为"byType"。这个时候guanyu bean会在上下文中寻找和weapon具有相同类型的类对应的bean。
因为Guanyu类的weapon实现Weapon借口,整个上下文中目前只有一个Weapon接口的实现Falchion类,所以以"byType"类型就检测到了falchion bean并将其注入到了guanyu bean的weapon属性中。
但是也会出现一种情况就是检测的时候可能会出现多个相同type的bean,这个时候就不知道要装配那个了。比如,我在新建一个实现Weapon接口的方天画戟类HalBerd:

package com.moonlit.myspring;public class Halberd implements Weapon {public void attack() {System.out.println("halberd is attacking!!!");}
}

并且在xml文件中声明一个新的halberd bean:

<bean id="halberd" class="com.moonlit.myspring.Halberd" />

在这种情况下就会出错,因为有两个bean满足byType的结果。

这个时候有两种解决办法:
第一种方法是将其中一个bean的primary属性设为false,比如:我们将方天画戟falchion bean的primary属性设为true,以防冠以使用方天画戟(很好奇吕布死了之后,赤兔马归关羽了,方天画戟去哪里了):

  <bean id="falchion" class="com.moonlit.myspring.Falchion"  /><bean id="halberd" class="com.moonlit.myspring.Halberd" primary="true" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="byType" />

输出结果如下:

GuanYu pick up his weapon.
halberd is attacking!!!

从输出结果中可以看到,关羽没有使用青龙偃月刀,而是使用方天画戟进行攻击了。

注:我看的Spring实战(第3版)上面说bean的默认primary属性默认是true,但是我这里用的是spring 4,根据效果来看primary的默认属性应该是false。
第二种方法是设置其中一个bean的autowire-candidate属性为false,比如:我们将方天画戟的autowire-candidate属性设为false:

  <bean id="falchion" class="com.moonlit.myspring.Falchion"  /><bean id="halberd" class="com.moonlit.myspring.Halberd" primary="true" autowire-candidate="false" /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="byType" />

这个时候测试程序的输出如下:

GuanYu pick up his weapon.
falcon is attacking!

可以看到这个时候关羽又重拾了青龙偃月刀。可以看到,当halberd bean的autowire-candidate属性设为false时,他将不会作为自动装配的竞选bean之一,这个时候虽然halberd的primary属性为true,但是halberd bean没有参与自动装配的竞选,所以自动装配到了falchion。

这种感觉就好像:“隔壁村李小花觊觎我已久,但我是一个要成为海贼王的男人,于是拒绝了她……最终她嫁给了隔壁老王,过上了幸福的生活”。

constructor自动装配

演示constructor之前我需要在在GuanYu类中添加一个构造函数:

    public GuanYu(Weapon weapon) {this.weapon = weapon;}

在xml文件中设置guanyu bean的autowire属性为constructor:

  <bean id="falchion" class="com.moonlit.myspring.Falchion"  /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="constructor" />

输出结果如下:

GuanYu pick up his weapon.
falcon is attacking!

实现了自动装配。

最佳自动装配

书上说是将autowire属性设为autodetect,但是我发现在我使用的spring 4(我看的书是spring 3)版本中没有autodetect,autowire属性只有byName,byType,constructor,default,no这些属性。

默认自动装配

可以在beans标签中添加default-autowire属性来设置默认自动装配策略,如:在beans标签中添加default-autowire="byType"设置默认自动装配策略为byType自动装配。

混合使用自动装配和显示装配

为了演示这个效果,我为Guanyu类添加了一个String成员变量name,虽然关羽就叫关羽,但是人家称呼他的时候还是会称呼他云长之类的。新定义的GuanYu类如下:

package com.moonlit.myspring;public class GuanYu implements Hero {private String name;private Weapon weapon;
//  public GuanYu(String name, Weapon weapon) {
//      this.name = name;
//      this.weapon = weapon;
//  }public void perform() {System.out.println(name + " pick up his weapon.");weapon.attack();}public Weapon getWeapon() {return weapon;}public void setWeapon(Weapon weapon) {this.weapon = weapon;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

(这里我注释掉了GuanYu类的构造函数。)

一个完全显示装配的例子如下:

  <bean id="falchion" class="com.moonlit.myspring.Falchion"  /><bean id="guanyu" class="com.moonlit.myspring.GuanYu"><property name="name"  value="Guan Yun Chang" /><property name="weapon" ref="falchion" /></bean>

当然,我们也可以使用显示装配和自动装配结合,显示装配name,自动装配weapon,如下:

  <bean id="falchion" class="com.moonlit.myspring.Falchion"  /><bean id="guanyu" class="com.moonlit.myspring.GuanYu" autowire="byType"><property name="name"  value="Guan Yun Chang" /></bean>

具有一样效果的输出。

使用混合装配的最后一个注意事项:当使用constructor自动装配策略时,我们必须让Spring自动装配构造器的所有入参——我们不能混合使用constructor自动装配策略和<constructor-arg>元素。

转载于:https://www.cnblogs.com/moonlightpoet/p/5569239.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sudo apt-get nmap 报错锁占用

在Ubuntu中用apt-get命令安装软件是出现如下错误&#xff1a; 网上搜了一下原因&#xff0c;说是有另外一个程序在运行&#xff0c;导致锁不可用&#xff0c;原因可能是赏析运行更新或安装没有正常完成。这是因为上次更新或者安装没有正常完成。 网上的两种解决方法&#xff1…

python逐行读取txt写入excel_用python从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)...

前几天接到一个任务&#xff0c;从gerrit上通过ssh命令获取一些commit相关的数据到文本文档中&#xff0c;随后将这些数据存入Excel中。数据格式如下图所示观察上图可知&#xff0c;存在文本文档中的数据符合一定的格式&#xff0c;通过python读取、正则表达式处理并写入Excel文…

筋斗云newcloud错误码列表

响应码信息备注440Ip Error客户送IP错误441Callee Number Error被叫号码位数错误&#xff08;标准11位正确&#xff0c;错误加前缀0&#xff0c;或其他前缀&#xff09;442Called Operator Error被叫运营商错误&#xff08;支持移动&#xff0c;不支持联通电信&#xff09;443N…

Extjs 之 initComponent 和 constructor的区别(转)

在创建自定义类时&#xff0c;先构造&#xff08;constructor)后初始化&#xff08;initComponent&#xff09;。如&#xff1a;&#xff08;在旧的Extjs 版本中使用 Ext.extend 实现扩展&#xff09; Ext.define(Btn,{ extend:Ext.button.Button, init…

hive遍历_从Hive中的stored as file_foramt看hive调优

一、行式数据库和列式数据库的对比1、存储比较行式数据库存储在hdfs上式按行进行存储的&#xff0c;一个block存储一或多行数据。而列式数据库在hdfs上则是按照列进行存储&#xff0c;一个block可能有一列或多列数据。2、压缩比较对于行式数据库&#xff0c;必然按行压缩&#…

oracle sql语句 从指定条数查询

现有表A 查询从第10行之后的数据 select a from ( select a, rownum r from A ) where r > 10 order by r; 实际工作中例子 select account,acct_name from ( select account, acct_name, rownum r from pmctl_nonsleep_acct ) where r > 10 order by

帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载

帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载 带索引书签目录高清版_13813212 下载链接http://pan.baidu.com/s/1geEmUeZ 【作 者】&#xff08;英&#xff09;蒂姆惠特尼&#xff08;TimWhitney&#xff09;著【丛书名】陪孩子成长系列丛书【形态项】 204 …

xwpftablecell设置字体样式_HTML的文字样式

font 属性可以用来作为 font-style, font-variant, font-weight, font-size, line-height 和 font-family 属性的简写&#xff0c;或将元素的字体设置为系统字体。字体修改font-family 属性&#xff1a;设置HTML页面中的字体font-size 属性&#xff1a;设置字体大小font-weight…

将中文标点符号替换成英文标点符号

/// 转全角的函数(SBC case) /// ///任意字符串 /// 全角字符串 /// ///全角空格为12288,半角空格为32 ///其他字符半角(33-126)与全角(65281-65374)的对应关系是&#xff1a;均相差65248 ///public string ToSBC(string input) { //半角转全角&#xff1a;char[] cinput.ToCh…

Centos6.5升级GCC

由于CentOS自带的gcc实在是老掉牙了&#xff0c;所以决定升级一下gcc&#xff0c;下面介绍如何进行源码编译&#xff0c;升级gcc。 从GNU网站下载你想要的gcc版本&#xff0c;链接&#xff1a;ftp://ftp.gnu.org/gnu/gcc/&#xff0c;选择合适的gcc版本&#xff0c;然后下载&am…

oracle sql语句 exists

exists 这个关键字只是个查询条件 用来判断后面跟的查询语句是否查找到记录 查找到为真 反之为假 例子 select * from ammst_corp a where account 999999999999999999 and exists ( select 1 from pmrgt_unit where unit_code a.open_unit ) 查找 9999999999999999…

python金字塔_高斯金字塔与拉普拉斯金字塔的原理与python构建

高斯金字塔和拉普拉斯金字塔【1】在图像相关领域应用广泛&#xff0c;尤其是图像融合和图像分割方面。本文从理论和opencv实现两个方面对两种金字塔进行了介绍&#xff0c;并给出了二者的视觉效果。1、高斯金字塔在计算机视觉与图像处理相关任务中&#xff0c;经常需要使用同一…

mongodb在32位机的连接

Windows 32bit版本安装Mongodb时&#xff0c;会发生的下面问题 2016-05-09T00:09:45.1240800 I STORAGE [initandlisten] exception in initAndListen: 28663 Cannot start server. The default storage engine wiredTiger is not available with this build of mongod. Pleas…

oracle sql 语句 start with ...... connect by prior .......

这个查询条件可以理解为递归查询 select up_unit_code from pmctl_nuit START WITH unit_code 1188899Q CONNECT BY PRIOR up_unit_code unit_code 语句理解&#xff1a; 首先根据条件 START WITH unit_code 查询到 up_unit_code 显示 然后 CONNECT BY P…

cnetos7安装zabbix3.0.3安装手册

亲测可用呀。学习好几天 最好用的文档详见附件http://down.51cto.com/data/2251232转载于:https://blog.51cto.com/11802086/1863554

python文件夹目录_Python 操作文件、文件夹、目录大全

#-*- coding: utf-8 -*-importosimportshutil#一. 路径操作&#xff1a;判断、获取和删除#1. 得到当前工作目录&#xff0c;即当前Python脚本工作的目录路径: os.getcwd()#print: currentpath: f:\LearnPythoncurrentpath os.getcwd()print "currentpath:",currentpa…

LightOJ 1370 Bi-shoe and Phi-shoe(欧拉函数)

题意&#xff1a;题目给出一个欧拉函数值F&#xff08;X&#xff09;&#xff0c;让我们求>这个函数值的最小数N&#xff0c;使得F&#xff08;N&#xff09; > F(X); 分析&#xff1a;这个题目有两种做法。第一种&#xff0c;暴力打出欧拉函数表&#xff0c;然后将它调整…

15-CSS基础-浮动流

浮动 网页的布局方式 什么是网页的布局方式? 网页的布局方式其实就是指浏览器是如何对网页中的元素进行排版的 标准流(文档流/普通流)排版方式 其实浏览器默认的排版方式就是标准流的排版方式在CSS中将元素分为三类, 分别是块级元素/行内元素/行内块级元素在标准流中有两种排版…

oracle sql 排序

当有多个排序列时 并且每列都是降序排序 需要在每个列名后 写desc

迁移DirectX11到VS2015 Win10

书本中的例子迁移&#xff1a;Introduction to 3D Game Programming with Direct3D 11.0 颜色&#xff1a;DirectXColors.h and the DirectX::Colors namespace. 效果&#xff1a;Effect framework编译后只需两个文件&#xff0c;d3dx11effect.h及生成的lib文件。 纹理&#xf…