zoukankan      html  css  js  c++  java
  • @Autowired与@Resource的区别

    @Autowired@Resource相同点 

    两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。

    @Autowired@Resource不同点


    1.@Autowired(org.springframework.beans.factory.annotation.Autowired)属于Spring的注解,@Resource(javax.annotation.Resource)属于J2EE的注解。
    2.@Autowired是通过byType注入的;@Resource是通过byName注入的;

    @Resource有2个重要的属性分别是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type则解析为bean的类型。所以使用name属性,则使用byName的自动注入策略,而使用byType属性时则使用byType自动注入策略。如果没用指定name或者type则默认通过byName自动注入策略。

    :最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。


    @Resource装配顺序

    ①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

    ②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

    ③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

    ④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

    @Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。

    代码演示:

    定义一个 接口  OrderMapper,二个实现类 OrderService01、OrderService02。一个 PayService 调用 orderMapper 接口中的方法。

    orderMapper

    package com.example.service;

    /**
    * @author mingtian
    * @version V1.0
    * @Description
    * @date 2019/12/9 16:57
    */
    public interface OrderMapper {
    /**
    * 新增订单方法
    */
    void add();
    }

    OrderServiceImpl01

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.stereotype.Component;

    /**
    * @author mingtian
    * @version V1.0
    * @Description 订单接口实现类
    * @date 2019/12/9 16:55
    */
    @Component
    public class OrderServiceImpl01 implements OrderMapper {
    public void add() {
    System.out.println("OrderService01");
    }
    }

    OrderServiceImpl02

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.stereotype.Component;

    /**
    * @author mingtian
    * @version V1.0
    * @Description 订单接口实现类
    * @date 2019/12/9 16:55
    */
    @Component
    public class OrderServiceImpl02 implements OrderMapper {
    public void add() {
    System.out.println("OrderService02");
    }
    }

    PayService 使用 @Auwowried

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * @author mingtian
    * @version V1.0
    * @Description PayService
    * @date 2019/12/9 16:54
    */
    @Component
    public class PayService {

    @Autowired
    private OrderMapper orderMapper;

    public void add() {
    orderMapper.add();
    }
    }

    配置类

    package com.example.config;

    import com.example.entity.Order;
    import com.example.entity.Win10;
    import org.springframework.context.annotation.*;

    /**
    * @author mingtian
    * @version V1.0
    * @Description
    * @ComponentScan("com.example.entity") //开启扫包范围
    * @date 2019/12/9 11:17
    */
    @Configuration
    @ComponentScan("com.example")
    public class MyConfig {

    }


    测试类

    package com.example.test;

    import com.example.config.MyConfig;
    import com.example.entity.FactoryBeanEntity;
    import com.example.service.impl.PayService;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;

    /**
    * @author mingtian
    * @version V1.0
    * @Description 测试类
    * @date 2019/12/9 11:00
    */
    public class Test005 {

    public static AnnotationConfigApplicationContext context;

    public static void main(String[] args) {
    context = new AnnotationConfigApplicationContext(MyConfig.class);
    PayService payService = (PayService) context.getBean("payService");
           payService.add();
    System.out.println("bean:" + payService);

    }
    }

    现在启动报错,错误信息如下:

    十二月 09, 2019 5:23:50 下午 org.springframework.context.support.AbstractApplicationContext refresh

    警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'payService': Unsatisfied dependency expressed through field 'orderMapper'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.service.OrderMapper' available: expected single matching bean but found 2: orderServiceImpl01,orderServiceImpl02

    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'payService': Unsatisfied dependency expressed through field 'orderMapper'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.service.OrderMapper' available: expected single matching bean but found 2: orderServiceImpl01,orderServiceImpl02

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)

    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)

    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)

    at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$31/221036634.getObject(Unknown Source)

    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)

    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)

    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)

    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)

    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89)

    at com.example.test.Test005.main(Test005.java:19)

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.service.OrderMapper' available: expected single matching bean but found 2: orderServiceImpl01,orderServiceImpl02

    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1265)

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)

    ... 15 more

    由上面报错的错误信息可知,通过 @Autowired 注解注入的 orderMapper 找到了二个实现类导致的错误。

    解决办法:

    方法1 使用 @Autowired + @Qualifier(value="orderServiceImpl01")  显示的指定一个实现类

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * @author mingtian
    * @version V1.0
    * @Description PayService
    * @date 2019/12/9 16:54
    */
    @Component
    public class PayService {

    @Autowired
    @Qualifier(value = "orderServiceImpl01")
    private OrderMapper orderMapper;

    public void add() {
    orderMapper.add();
    }
    }

    方法2  使用@Resource(name="orderServiceImpl01")

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * @author mingtian
    * @version V1.0
    * @Description PayService
    * @date 2019/12/9 16:54
    */
    @Component
    public class PayService {

    @Resource(name = "orderServiceImpl01")
    private OrderMapper orderMapper;

    public void add() {
    orderMapper.add();
    }
    }

    由上面的二种解决方法可知:

     @Autowired + @Qualifier(value="orderServiceImpl01") 等同于 @Resource(name="orderServiceImpl01")

    方法3 使用 @Primary 注解 指定默认加载的类,这样的话 直接在PayService 中 直接使用 @Autowired  一个注解即可,默认启动就会加载 OrderServiceImpl01 这个类

    package com.example.service.impl;

    import com.example.service.OrderMapper;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Component;

    /**
    * @author mingtian
    * @version V1.0
    * @Description 订单接口实现类
    * @date 2019/12/9 16:55
    */
    @Primary
    @Component
    public class OrderServiceImpl01 implements OrderMapper {
    public void add() {
    System.out.println("OrderService01");
    }
    }

    @Primary 这个注解 在 SpringBoot 多数据源的时候经常使用 ,用来设置加载默认的数据源(优先级)。

    注意:使用 @Component 注解的时候,记得开启扫包的范围(使用 @ComponentScan("com.example")指定扫包范围),不然启动会报错的。

     OrderMapper,二个实现类 OrderService01、OrderService02、

  • 相关阅读:
    JavaScript 中,定义函数时用 var foo = function () {} 和 function foo() 有什么区别?
    Vue报错 [Vue warn]: Cannot find element
    一个android样本的过保护
    cve-2015-1635漏洞分析
    一个linux的样本分析
    ios透明代理抓包
    各浏览器抗uaf机制
    面试知识点总结之Nginx
    面试知识点总结之redis
    面试知识点总结之I/O流IO/BIO/NIO/AIO区别
  • 原文地址:https://www.cnblogs.com/ming-blogs/p/10288964.html
Copyright © 2011-2022 走看看