前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring bean注解配置(2)—— @Autowired

Spring bean注解配置(2)—— @Autowired

作者头像
浩Coding
发布2019-07-03 12:52:35
1.2K0
发布2019-07-03 12:52:35
举报
文章被收录于专栏:浩Coding浩Coding

@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法系统自动为你注入,即隐式配置。自动装配的意思就是:找到合适的Bean注入给这个注释变量。

在使用@Autowired之前,我们对一个bean配置属性时,用XML配置是这样用的:

代码语言:javascript
复制
<property name="属性名" value=" 属性值"/>  

但是通过这种方式来,配置比较繁琐,而且代码比较多。在Spring 2.5 引入了 @Autowired 注释。

注意事项:

在使用@Autowired时,首先在容器中查询对应类型的bean。

  如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据。

如果查询的结果不止一个,那么@Autowired会根据名称来查找

  如果查询的结果为空,那么会抛出异常。

解决方法一:使用required=false。

解决方法二:加一个@Qualifier标记,来指定需要装配bean的名称,代码这样写:

代码语言:javascript
复制
@Autowired
@Qualifier("dao的其他自定义名称")
private Dao dao;

@Autowired 注释的具体案例说明:

代码语言:javascript
复制
package autowired;

public interface Dao {
  public void Print() ;
}
代码语言:javascript
复制
package autowired;

import org.springframework.stereotype.Repository;

@Repository
public class DaoImp implements Dao {

  @Override
  public void Print() {
    System.out.println("DaoImp Print:");
  }

}

这是一个接口Dao和他的实现类DaoImp,其中一个方法就是Print()。在DaoImp,有@Repository,默认指定了该bean在IoC中标识符名称为“daoImp”。

代码语言:javascript
复制
package autowired;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ServiceTest {
  @Autowired
  private DaoImp daoImp;

  public void Print() {
    daoImp.Print();
  }
}

这里用了一个DaoImp类型的属性,通过@Autowired自动装配方式,从IoC容器中去查找到,并返回给该属性。

applicationContext.xml配置:

代码语言:javascript
复制
<context:component-scan base-package="autowired"/>

测试代码:

代码语言:javascript
复制
ApplicationContext appCon = new ClassPathXmlApplicationContext("annotationContext.xml");
ServiceTest serviceTest = (ServiceTest) appCon.getBean("serviceTest");
serviceTest.Print();

输出结果:

代码语言:javascript
复制
DaoImp Print:

这里有个有意思的问题,关于用接口类型还是实现类类型的问题,看代码:

代码语言:javascript
复制
@Service
public class ServiceTest {
  @Autowired
  private DaoImp daoImp;
//  private Dao dao;
// 这里用接口类型也可以,实现类 类型也可以,@Autowired会自动装配

  public void Print() {
    daoImp.Print();
  }
}

我们测试后发现:这里用接口类型也可以,实现类 类型也可以,@Autowired会自动装配,结果是一样的。

由于针对接口编程,因此很有可能多个类实现了同一个接口这时Spring如果扫描到多个匹配对象,导致Spring不知道选择哪个好,那Spring不客气的就会报错了,所以,如果用接口类型的话,可以用以下方法避免出错:

1、设置首选的Component,通过@Primary进行标注(如果多处都标注,依然出现歧义性问题);

2、限定自动装配的bean,在自动装配注解出添加注解@Qualifier(“name”),其中name为bean的ID(默认bean ID为类名首字母小写);如果重命名了组件类,那么自动装配将会失败。

3、通过自定义的限定符,其实就是在组件类与自动装配处,同时注解Qualifier(“name”),name为自定义且两出相同。

4、通过使用自定义的限定符注解,例如我用使用@Cold来标注组件类和自动装配两处。那么@Cold怎么自定义呢?我们需要自定义下该注解。

代码语言:javascript
复制
@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{}

@Autowired 在Spring2.5引入,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。下面是例子:

写一个测试用的接口,这里命名为光盘(CompactDisc):

代码语言:javascript
复制
public interface CompactDisc {
    void play();
}

利用注解@Component声明一个组件类:

代码语言:javascript
复制
@Component
public class SgtPeppers implements CompactDisc{
    @Override
    public void play() {
        System.out.println("SgtPeppers    playing....");
    }
}

编写一个Player类,进行@Autowired,装配类。实现方式有三种,如下所示:

在方法上:

代码语言:javascript
复制
public class CDPlayer {
    CompactDisc cd;   
    //对方法进行标注
    @Autowired
    public void setCompactDisc(CompactDisc cd){
        this.cd = cd;
    }
    public void say(){
        cd.play();
    }
}

在成员变量上:

代码语言:javascript
复制
public class CDPlayer{
     //对成员变量进行标注
     @Autowired
     CompactDisc cd;
     public void say(){
          cd.play();
     }
}

在构造函数上:

代码语言:javascript
复制
public class CDPlayer {
    CompactDisc cd;   
    //对构造函数进行标注
    @Autowired
    public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }
    public void say(){
        cd.play();
    }
}

注意:如果构造函数有两个入参,分别是 bean1 和 bean2,@Autowired 将分别寻找和它们类型匹配的 Bean。

拓展篇

1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

代码语言:javascript
复制
@Autowired() @Qualifier("baseDao")     
private BaseDao baseDao;    

3、@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定,

如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配,如下所示。

代码语言:javascript
复制
@Resource(name="baseDao")     
private BaseDao baseDao;    

用 @Resource注解在字段上,且这个注解是属于J2EE的,减少了与spring的耦合。个人还是习惯用@Autowired。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 浩Coding 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拓展篇
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档