专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  Spring用到了哪些设计模式? ·  9 小时前  
Java编程精选  ·  减少 try catch ,可以这样干! ·  2 天前  
芋道源码  ·  这样画时序图,真香! ·  昨天  
芋道源码  ·  四种 API 架构风格 ·  2 天前  
Java编程精选  ·  雷军提出建议!他本人也曾是“受害者” ·  3 天前  
51好读  ›  专栏  ›  ImportNew

Spring 9 : Autowire ( 自动装配 ) 机制

ImportNew  · 公众号  · Java  · 2017-05-28 13:13

正文

(点击 上方公众号 ,可快速关注)


来源:五月的仓颉,

www.cnblogs.com/xrq730/p/6706128.html

如有好文章投稿,请点击 → 这里了解详情


为什么Spring要支持Autowire(自动装配)


先写几个类,首先定义一个Animal接口表示动物:


public interface Animal {

public void eat();

}


写一个Animal接口的实现Tiger类:


public class Tiger implements Animal {

@Override

public void eat() {

System.out.println("Tiger.eat()");

}

@Override

public String toString() {

return "I'm a 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:


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-3.0.xsd">


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进行属性装配,那么将改成以下的形式:


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-3.0.xsd"

default-autowire="byName">


看到Zoo中有一个名为animal的属性,我将Tiger这个bean也命名为animal,由于Tiger是Animal接口的实现类,因此Spring可以找到beanName为animal的bean并自动装配到Zoo的animal属性中,这就是byName的自动装配形式。


接着看一下byType的自动装配形式,byType意为在spring配置文件中查询与属性类型一致的bean并进行装配,若有多个相同类型则报错(下一部分讲),autowire.xml如果使用byType进行属性装配,那么将改成以下的形式:


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-3.0.xsd"

default-autowire="byType">


将Tiger命名为tiger(将bean命名为类名首字母小写也比较符合规范),由于Tiger是Animal接口的实现类,因此Spring找到了Tiger并自动装配到Zoo的animal属性中,这就是byType的自动装配形式。


byType装配出现多个相同类型的bean及解决方案


前面演示了,byType的装配方式是在Spring配置文件中寻找属性类型与bean类型一致的bean,那么有一个问题,就是如果属性类型在Spring配置文件中有多个相同类型的bean会出现什么样的情况?为了探究一下这个问题,先定义另外一个Animal接口的实现类,叫做lion:


public class Lion implements Animal {

@Override

public void eat() {

System.out.println("Lion.eat()");

}

@Override

public String toString() {

return "I'm a lion";

}

}


接着,在Spring配置文件中定义一下Lion这个类:


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-3.0.xsd"

default-autowire="byType">


运行一个测试类,结果为:


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)







请到「今天看啥」查看全文


推荐文章
芋道源码  ·  Spring用到了哪些设计模式?
9 小时前
Java编程精选  ·  减少 try catch ,可以这样干!
2 天前
芋道源码  ·  这样画时序图,真香!
昨天
芋道源码  ·  四种 API 架构风格
2 天前
质量与认证  ·  在公司混日子,伤害的最终是自己
7 年前
深圳百事通  ·  住宝安区的人,你们又要令人羡慕了!
7 年前