Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7096937
  • 博文数量: 703
  • 博客积分: 10821
  • 博客等级: 上将
  • 技术积分: 12042
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-02 10:41
个人简介

中科院云平台架构师,专注于数字化、智能化,技术方向:云、Linux内核、AI、MES/ERP/CRM/OA、物联网、传感器、大数据、ML、微服务。

文章分类

全部博文(703)

分类: Java

2013-05-14 18:28:05

在最近的一个用到Spring项目中,大量用到@Autowired。但要慎用。
先说一下怎么用:
Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。
Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。  
在applicatonContext.xml中 把原来 引用的标签去掉。

具体使用方法可参照:http://blog.csdn.net/heyutao007/article/details/5981555

然后看一下反方的观点:
Spring
2之后,出现很多注解,这些注解让Spring的配置变得混乱起来。
注解引发的问题:
1、缺乏明确的配置导致程序的依赖注入关系不明确。
2、不利于模块化的装配。
3、给维护带来麻烦,因为你要根据源代码找到依赖关系。
4、通用性不好。如果你哪天抛开了Spring,换了别的Ioc容器,那么你的注解要一个个的删除。

当然这位高人显然过于自信。
我也大多同意他的看法。但在以下场合建议用。
1:接口实现类有限,扩展性要求不高。
2:业务明确,需求固定,工作量大的场合。使用后,代码减少,从业务的观点看代码。更易读。
3:在良好的代码规范约束下。

以下引用出现的一个问题:
package com.hiya.test;
  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
  
@Component
public class A {
    @Autowired
    B b;
}


package com.hiya.test;
  
import org.springframework.stereotype.Component;
  
@Component
public class B {
     public  void  BMethod(){};
}

package com.hiya.test;
  
public abstract interface IB   {
}
启动时报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': 
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b; 
nested exception is java.lang.IllegalArgumentException: 
Can not set com.hiya.test.B field com.siqisoft.test.A.b to $Proxy23
解决案:
案1:@Autowired  
    @Qualifier("b")  //用B类型去注入. 请注意类名首字母小写
  private IB b
案2:
 
A类的成员变量改为IB接口
@Component
public class B 的
@Component去掉

原因:
在使用Spring框架中@Autowired标签时默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出
BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。
Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称,这样歧义就消除了,可以通过下面的方法解决异常。
@Qualifier("XXX") 中的 XX是 Bean 的名称,所以 @Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。
@Autowired 可以对、方法以及构造函数进行注释,而 @Qualifier 的标注对象是成员变量、方法入参、构造函数入参。



阅读(33529) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~