IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring中的@Autowired和@Resource注解对比 -> 正文阅读

[Java知识库]Spring中的@Autowired和@Resource注解对比

简介

@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,但是Spring支持该注解的注入。

本文代码已经上传至 gitee

简单对比

相同点

  • 都能进行依赖注入,可以加到属性上也可以加到setter方法上。

不同点

@Autowired注解

  • @Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false
  • @Autowired注解装配对象如果根据类型能匹配到多个,可以通过@Qualifier指定名称通过名称注入。(优先级 高)
  • @Autowired注解装配对象如果根据类型能匹配到多个,可以在对应的需要注入的类上添加@Primary注解,来指定默认注入的对象(注意优先级不如@Qualifier)。 (优先级 中)
  • @Autowired注解装配对象如果根据类型能匹配到多个,则会按照属性名再去匹配找到对应的bean。(优先级 低)

@Resource注解

  • @Resource默认按照ByName自动注入。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
  • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  • 如果指定了name,则从上下文中查找名称匹配的bean进行装配,找不到则抛出异常
  • 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

代码实战验证

@Autowired验证

// 验证一:@Qualifier注解配合使用

public interface AutowiredInterface {
    /**
     * 接口方法
     */
    void sayAutowired();
}



@Component
@Data
public class AutowiredBean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

@Component
@Data
public class Autowired02Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

// 不结合 @Qualifier注解,启动直接报错
@Service
public class TestService {

    @Autowired
//    @Qualifier(value = "autowired02Bean")
    private AutowiredInterface autowiredInterface;

    public void say() {
        System.out.println("开始说。。");
        autowiredInterface.sayAutowired();
        System.out.println("实际注入的对象:"+autowiredInterface.getClass());
    }

}

// 结合 @Qualifier注解,正常启动
@Service
public class TestService {

    // value 为指定的bean的名称
    @Autowired
    @Qualifier(value = "autowired02Bean")
    private AutowiredInterface autowiredInterface;

    public void say() {
        System.out.println("开始说。。");
        autowiredInterface.sayAutowired();
        System.out.println("实际注入的对象:"+autowiredInterface.getClass());
    }

}

// 验证二: @Primary注解结合使用
public interface AutowiredInterface {

    /**
     * 接口方法
     */
    void sayAutowired();
}

@Service
public class TestService {

    @Autowired
//    @Qualifier(value = "autowired02Bean")
    private AutowiredInterface autowiredInterface;

    public void say() {
        System.out.println("开始说。。");
        autowiredInterface.sayAutowired();
        System.out.println("实际注入的对象:"+autowiredInterface.getClass());
    }
}

@Component
@Data
public class AutowiredBean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

// 不结合 @Primary 启动报错
@Component
@Data
// @Primary
public class Autowired02Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

// 结合 @Primary 正常启动
@Component
@Data
@Primary
public class Autowired02Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}
// 验证三: 通过属性名注入bean
public interface AutowiredInterface {

    /**
     * 接口方法
     */
    void sayAutowired();
}


@Component
@Data
public class AutowiredBean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

@Component
@Data
// @Primary
public class Autowired02Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

@Service
public class TestService {

    // 属性名和具体实现的beanName不一致,启动报错
    @Autowired
//    @Qualifier(value = "autowired02Bean")
    private AutowiredInterface autowiredInterface;

    public void say() {
        System.out.println("开始说。。");
        autowiredInterface.sayAutowired();
        System.out.println("实际注入的对象:"+autowiredInterface.getClass());
    }
}


// 属性名和具体实现的一致,能成功注入启动
@Service
public class TestService {

    // 属性名和具体实现的beanName一致,启动成功
    @Autowired
//    @Qualifier(value = "autowired02Bean")
    private AutowiredInterface autowired02Bean;

    public void say() {
        System.out.println("开始说。。");
        autowired02Bean.sayAutowired();
        System.out.println("实际注入的对象:"+autowired02Bean.getClass());
    }
}
// 验证四: 验证上述三种的优先级
public interface AutowiredInterface {

    /**
     * 接口方法
     */
    void sayAutowired();
}


@Component
@Data
public class AutowiredBean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}

@Component
@Data
@Primary
public class Autowired02Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}


@Component
@Data
public class Autowired03Bean implements AutowiredInterface{
    private String  name;

    @Override
    public void sayAutowired() {
        System.out.println("autowired:"+name);
    }
}


// 接口有三个实现,上面三种分别命中其中的bean,看哪个能具体生效(两个直接的对比只要控制变量即可测出,这里只演示这里,其他自测即可,这里直接给出测出的结果如下: @Qualifier > @Primary > 属性名)
@Service
public class TestService {

    @Autowired
    @Qualifier(value = "autowiredBean")
    private AutowiredInterface autowired03Bean;

    public void say() {
        System.out.println("开始说。。");
        autowired03Bean.sayAutowired();
        System.out.println("实际注入的对象:"+autowired03Bean.getClass());
    }

}


@Resource验证

//这个验证前面的类可以不变,只要改注入的那部分代码即可,通用代码如下
public interface ResourceInterface {

    /**
     * 接口方法
     */
    void sayResource();
}

@Component
@Data
public class ResourceBean implements ResourceInterface {
    private String  name;

    @Override
    public void sayResource() {
        System.out.println("resource:"+name);
    }
}

@Component
@Data
public class Resource02Bean implements ResourceInterface {
    private String  name;

    @Override
    public void sayResource() {
        System.out.println("resource:"+name);
    }
}

@Component
@Data
public class Resource03Bean implements ResourceInterface {
    private String  name;

    @Override
    public void sayResource() {
        System.out.println("resource:"+name);
    }
}
// 验证一: 既不指定name也不指定type,默认走name,如果没匹配则尝试type,匹配不到报错
@Service
public class TestService {

    @Resource
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }

}

// 验证二: 只指定type,默认走name,如果没有或者也多个则报错
@Service
public class TestService {

    @Resource(type = ResourceInterface.class)
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }

}

// 验证三: 只指定name,匹配不到报错(spring中的beanName是要唯一的,所以不存在匹配多个)
@Service
public class TestService {
    @Resource(name = "hahaha")
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }

}

// 验证四: 既指定name也指定type,默认匹配同时满足的bean,匹配不到报错
@Service
public class TestService {
	// 无法匹配
    @Resource(name = "hahaha",type = ResourceInterface.class)
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }

}

@Service
public class TestService {
    // 无法匹配
    @Resource(name = "resourceBean",type = AutowiredInterface.class)
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }

}

@Service
public class TestService {
	// 正确匹配
    @Resource(name = "resourceBean",type = ResourceInterface.class)
    private ResourceInterface resourceInterface;

    public void sayResource() {
        System.out.println("开始说。。");
        resourceInterface.sayResource();
        System.out.println("实际注入的对象:"+resourceInterface.getClass());
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:27:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:57:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码