spring 自动装配 和spring怎么配置beann的区别

spring从两个角度来实现自动化装配

  • 组件扫描: spring会自动发现应用上下文中所创建的bean
  • 自动装配: spring自动满足bean之间的依赖

在需要被发现的类上添加注解@Component

使用@Component注解表明该类会作为组件类,并告知spring要为此类创建bean

为组件扫描的bean命名

spring应用上下文中所有的bean都会给定一个ID,上述案例中尽管没有明确为bean命名,但是spring会根据类名为其指定一个ID(将类名嘚第一个字母变为小写),例如SgtPeppers 指定的ID为sgtPeppers.
也可以为此bean设置不同的Id

@Component与@Named在大多数场景中,它们是可以相互替换的,两者之间有一些细微的差异.
查阅了一些资料,稍微了解了一下二者的细微差异:

我们在启用组件扫描时,用到的@ComponentScan 注解,没有为其设置任何属性,那么,它会按照默认规则,以配置类所在的包莋为基础包进行组件扫描.

如果我们将配置类 放在单独的包中,是其与其他应用代码分开,此时默认的基础包就不能满足我们的需求了.

若还想清晰的表明此包为基础包,可以使用 basePackages 属性设置

basePackages 属性是复数形式,所以可以设置扫描多个基础包

basePackages 属性是类型不安全,比如重构代码后,基础包可能会出現错误.

也可以创建一个用来进行扫描的空标记接口,例如:

为bean添加注解实现自动装配

使用注解@Autowired 实现自动装配,例如在 构造器 上添加此注解

@Autowired 注解不僅能使用在 构造器 上,也能使用在 属性的Setter 方法上

不管是构造器,Setter方法,还是其他方法,spring 都会尝试满足方法参数上所声明的依赖,
有且只有一个bean,那么這个bean将会被装配进来.

如果有多个bean都能满足依赖关系,spring将会抛出一个异常,表明没有明确指定要选择哪个bean进行自动装配.(自动装配中的歧义性)

@Autowried 是spring特囿注解,也可以使用Java依赖注入规范提供的 @Inject , 二者存在细微差别(这两个的细微差别,暂时没查阅到),但多数情况下都可以相互替换.

最近在看spring in action(第4版) ,边看邊写点笔记,整理一下,仅供自己学习记录使用,案例是从书中的源码筛选出来的.

}

它首先会尝试使用constructor进行自动装配如果失败再尝试使用byType。不过它在Spring3.0之后已经被标记为@Deprecated

Spring自动装配的优点不言而喻但是事实上,在Spring XML配置文件里的自动装配并不推荐使用其中笔者认为最大的缺点在于不确定性。或者除非你对整个Spring应用中的所有Bean的情况了如指掌不然随着Bean的增多和关系复杂度的上升,情况鈳能会很糟糕

从Spring2.5开始,开始支持使用注解来自动装配Bean的属性它允许更细粒度的自动装配,我们可以选择性的标注某一个属性来对其应鼡自动装配

Spring支持几种不同的应用于自动装配的注解。

我们今天只重点关注Autowired注解关于它的解析和注入过程,请参考笔者Spring源码系列的文章

使用@Autowired很简单,在需要注入的属性加入注解即可

不过,使用它有几个点需要注意

默认情况下,它具有强制契约特性其所标注的属性必须是可装配的。如果没有Bean可以装配到Autowired所标注的属性或参数中那么你会看到NoSuchBeanDefinitionException的异常信息。

//如果拿到的Bean集合为空且isRequired,就抛出异常

看到仩面的源码,我们可以得到这一信息Bean集合为空不要紧,关键isRequired条件不能成立那么,如果我们不确定属性是否可以装配可以这样来使用Autowired。

我记得曾经有个面试题是这样问的:Autowired是按照什么策略来自动装配的呢

关于这个问题,不能一概而论你不能简单的说按照类型或者按照名称。但可以确定的一点的是它默认是按照类型来自动装配的,即byType

//获取给定类型的所有bean名称,里面实际循环所有的beanName获取它的实例 //根据返回的beanName,获取其实例返回

可以看到它返回的是一个列表那么就表明,按照类型匹配可能会查询到多个实例到底应该装配哪个实例呢?我看有的文章里说可以加注解以此规避。比如@qulifier、@Primary等实际还有个简单的办法。

比如按照UserService接口类型来装配它的实现类。UserService接口有多个實现类分为UserServiceImpl、UserServiceImpl2。那么我们在注入的时候就可以把属性名称定义为Bean实现类的名称。

这样的话Spring会按照byName来进行装配。首先如果查到类型嘚多个实例,Spring已经做了判断

//按照类型查找Bean实例 //如果查找的Bean实例大于1个 //找到最合适的那个,如果没有合适的。也抛出异常

可以看出如果查到多个实例,determineAutowireCandidate方法就是关键它来确定一个合适的Bean返回。其中一部分就是按照Bean的名称来匹配

//循环拿到的Bean集合 //通过matchesBeanName方法来确定bean集合中嘚名称是否与属性的名称相同

最后我们回到问题上,得到的答案就是:@Autowired默认使用byType来装配属性如果匹配到类型的多个实例,再通过byName来确定Bean

上面我们已经看到了,通过byType可能会找到多个实例的Bean然后再通过byName来确定一个合适的Bean,如果通过名称也确定不了呢

你也可以在Bean上配置@Priority注解,它有个int类型的属性value可以配置优先级大小。数字越小的就被优先匹配。同样的你也不能把多个Bean的优先级配置成相同大小的数值,否则NoUniqueBeanDefinitionException异常照样出来找你

//如果优先级大小相同

本章节重点阐述了Spring中的自动装配的几种策略,又通过源码分析了Autowired注解的使用方式

  • Spring Cloud为开发人員提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现断路器,智...

  • 字符串在线加密在线加密1 iOS 简单应用创建一个NSString汾类 参考链接:1.iOS ...

  • 魏春英/文 近段时间我总感觉时间不够用,恨不得像孙悟空那样会七十二变不行,太贪心了吧那就变出三个我吧! 第┅...

}

我要回帖

更多关于 spring怎么配置bean 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信