设为首页收藏本站

小牛社区-大数据学习交流社区|大数据免费学习资源

 找回密码
 立即注册!

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 216|回复: 0

Spring9:Autowire(自动装配)机制

[复制链接]

97

主题

0

帖子

30

积分

吃土小白

Rank: 1

积分
30
发表于 2017-10-24 16:01:38 | 显示全部楼层 |阅读模式
  先写几个类,首先定义一个Animal接口表示动物:
  写一个Animal接口的实现Tiger类:
  写一个动物园类Zoo,持有Animal接口,表示动物园中有动物:
public class Zoo { 
  private Animal animal;
  public Animal getAnimal() {
  return animal;
  }
  public void setAnimal(Animal animal) {
  this.animal = animal;
  }
  @Override
  public String toString() {
  if (animal == null) {
  return null;
  }
  return animal.toString();
  }
}
  配置一下spring文件,由于这个功能研究的是Autowire,因此我命名为autowire.xml:
 
 
  
  
  
  

  Spring引入Autowire(自动装配)机制就是为了解决标签下标签过多的问题,标签过多会引发两个问题: 
如果一个Bean中要注入的对象过多,比如十几二十个(这是很正常的),那将导致Spring配置文件非常冗长,可读性与维护性差
如果一个Bean中要注入的对象过多,配置麻烦且一不小心就容易出错
  因此,为了解决使用标签注入对象过多的问题,Spring引入自动装配机制,简化开发者配置难度,降低xml文件配置大小。
使用Autowire去除标签 
  下面来看一下使用Autowire去除,autowire有两处点:
可以配置在根标签下,表示对全局起作用,属性名为default-autowire
可以配置在标签下,表示对当前起作用,属性名为autowire
  通常都是在根标签下配置自动装配比较多,default-autowire有四种取值:
no:默认,即不进行自动装配,每一个对象的注入比如依赖一个标签
byName:按照beanName进行自动装配,使用setter注入
byType:按照bean类型进行自动装配,使用setter注入
constructor:与byType差不多,不过最终属性通过构造函数进行注入
  这里研究的是去除标签,因此第一种不管;constructor装配不太常用,因此这里也不管,重点看最常用的byName与byType,至于具体使用哪种根据自己的业务特点进行相应的设置。
  首先看一下byName,byName意为在spring配置文件中查询beanName与属性名一致的bean并进行装配,若类型不匹配则报错,autowire.xml如果使用byName进行属性装配,那么将改成以下的形式: 
 

  
  

  看到Zoo中有一个名为animal的属性,我将Tiger这个bean也命名为animal,由于Tiger是Animal接口的实现类,因此Spring可以找到beanName为animal的bean并自动装配到Zoo的animal属性中,这就是byName的自动装配形式。
  接着看一下byType的自动装配形式,byType意为在spring配置文件中查询与属性类型一致的bean并进行装配,若有多个相同类型则报错(下一部分讲),autowire.xml如果使用byType进行属性装配,那么将改成以下的形式: 
 

  
  

  将Tiger命名为tiger(将bean命名为类名首字母小写也比较符合规范),由于Tiger是Animal接口的实现类,因此Spring找到了Tiger并自动装配到Zoo的animal属性中,这就是byType的自动装配形式。
byType装配出现多个相同类型的bean及解决方案 
  前面演示了,byType的装配方式是在Spring配置文件中寻找属性类型与bean类型一致的bean,那么有一个问题,就是如果属性类型在Spring配置文件中有多个相同类型的bean会出现什么样的情况?为了探究一下这个问题,先定义另外一个Animal接口的实现类,叫做lion:
  接着,在Spring配置文件中定义一下Lion这个类:
 

  
  
  

  运行一个测试类,结果为:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'zoo' defined in class path resource [spring/autowire.xml]:  
Unsatisfied dependency expressed through bean property 'animal': : No unique bean of type [org.xrq.action.by.Animal] is defined: expected single matching bean but  
found 2: [tiger, lion]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.xrq.action.by.Animal] is  
defined: expected single matching bean but found 2: [tiger, lion] 
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1166)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1058)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:516)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
  意思很明显:想要通过byType方式为animal进行装配却找到了两个符合要求的bean,分别为tiger与lion,这导致了没有唯一的bean可以对animal进行装配。
  这个问题有两种解决方案,假如现在我要装配的是lion这个bean,第一种解决方案是将不需要进行自动装配的bean进行排除,对不需要进行自动装配的bean设置属性autowire-candidate=”false”即可: 
 

  
  
  

  candidate顾名思义,即候选人的意思,autowire-candidate=”false”即这个bean我不想让它作为自动装配的候选者,既然tiger不是自动装配的候选者,那么animal类型在Spring容器中能自动装配的也就只有一个lion了,Spring自动装配lion,不会有问题。
  第一种思路是排除那些不需要作为自动装配候选者的bean,第二种思路就从相反逻辑出发,设置当发现有多个候选者的时候优先使用其中的哪个候选者,对要作为自动装配候选者的bean设置primary=”true”即可: 
 

  
  
  

  这种方式同样也可以将lion装配到animal属性中而不会报错。

少加空判断,很有道理 get!!!  千阳 
关于ImportNew 
  ImportNew 专注于 Java 技术分享。于2012年11月11日 11:11正式上线。是的,这是一个很特别的时刻 :)
  ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……

小组 – 好的话题、有启发的回复、值得信赖的圈子 
头条 – 写了文章?看干货?去头条! 
相亲 – 为IT单身男女服务的征婚传播平台 
资源 – 优秀的工具资源导航 
翻译 – 活跃 & 专业的翻译小组 
博客 – 国内外的精选博客文章 
设计 – UI,网页,交互和用户体验 
前端 – JavaScript, HTML5, CSS 
安卓 – 专注Android技术分享 
iOS – 专注iOS技术分享 
Java – 专注Java技术分享 
Python – 专注Python技术分享 

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册!

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册!

本版积分规则

快速回复 返回顶部 返回列表