@Autowired

1、属于spring的注解,如果不想和Spring耦合的太紧,就不推荐使用。

2、默认情况下,要求依赖对象必须存在,不能为null。如果允许为空,那么设置属性值required为false。

3、默认按照类型装配(byType)。到底什么是类型装配,看下边的例子:

情形1:

public interface UserService {
}

@Service
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
   @Autowired
   private UserService userService;
}

分析:在上边的测试类中使用@Autowired注入时,编辑器会报错:

Could not autowire. There is more than one bean of 'UserService' type.
Beans:
userServiceImpl   (UserServiceImpl.java)
userServiceImpl2   (UserServiceImpl2.java)

原因是,@Autowired是默认按照类型注入的,它就告诉代码,我就需要一个UserService类型的类就行,但是代

码却有两个UserService类型的类。这时,@Autowired还可以按照名称(userService)注入,但是也没有满足的bean,就报错了。

情形2:

public interface UserService {
}

@Service("userService")
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Autowired
  private UserService userService;
   
  @org.junit.Test
  public void test1(){  
  System.out.println(userService);
  }
}

打印:
demo.springboot.Service.UserServiceImpl@47b11ec7

分析:这时@Autowired是按照名称注入的。

情形3:

public interface UserService {
}

@Service("myUserService")
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Autowired
  @Qualifier("myUserService")
  private UserService userService;
   
  @org.junit.Test
  public void test1(){  
  System.out.println(userService);
  }
}

打印:
demo.springboot.Service.UserServiceImpl@47b11ec7

分析:这时如果UserServiceImpl有个别名”myUserService“,那么@Autowired需要和 @Qualifier配合使用,然后根据@Qualifier中的属性值,按照名称注入。

情形4:

public interface UserService {
}

@Service
public class UserServiceImpl implements UserService {
}

@Service
@Primary
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Autowired
  private UserService userService;
   
  @org.junit.Test
  public void test1(){  
  System.out.println(userService);
  }
}

打印:
demo.springboot.Service.UserServiceImpl2@6a756082

分析:如果在UserServiceImpl或者UserServiceImpl2上加上@Primary,就有了一个优先的顺序,就会注入加了@Primary注解的类

@Resource

1、属于J2EE JSR250规范的实现。所以建议使用@Resource注解,以减少代码和Spring之间的耦合。

2、默认按照名称装配(byName),什么是安装名称装配,看下面的例子:

情形1:

public interface UserService {
}

@Service
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Resource
  private UserService userService;

  @org.junit.Test
  public void test1() {
      System.out.println(userService);
  }
}

分析:执行代码会报错:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demo.springboot.Test': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'demo.springboot.Service.iface.UserService' available: expected single matching bean but found 2: userServiceImpl,userServiceImpl2

这个报错很明显,虽然编译器在起初没有报错,但是由于@Resource是默认按照名称注入的,@Resource想要一个bean的name是userService的,但是却没有,UserServiceImpl和UserServiceImpl2的beanName默认为类名小写。所以这时匹配不上名称,就会按照类型注入,但是却发现两个类型UserService的类,所以报错了(expected single matching bean but found 2)。

情形2:

public interface UserService {
}

@Service("userService")
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Resource
  private UserService userService;

  @org.junit.Test
  public void test1() {
      System.out.println(userService);
  }
}

打印:
demo.springboot.Service.UserServiceImpl@727320fa

分析:给UserServiceImpl的beanName写为userService,这时@Resource按照name注入了。

情形3:

public interface UserService {
}

@Service
@Primary
public class UserServiceImpl implements UserService {
}

@Service
public class UserServiceImpl2 implements UserService {
}

@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
  @Resource
  private UserService userService;

  @org.junit.Test
  public void test1() {
      System.out.println(userService);
  }
}

打印:
demo.springboot.Service.UserServiceImpl@44784e2f

分析:加了@Primary,@Resource就可以按照类型注入了。

@Qualifier

1、在给字段注入时,不能独立使用,必须和@Autowired配合使用。

2、给方法参数注入时,可以独立使用。

@Autowired、@Resource、@Qualifier区别的更多相关文章

  1. @Resource、@Autowired、@Qualifier 区别(表格显示)

    @Resource.@Autowired.@Qualifier 区别(表格显示) 区别项 @Resource @Autowired @Qualifier 谁提供的 jdk提供,包是javax.anno ...

  2. @Autowired @Resource @Qualifier的区别

    参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/det ...

  3. Spring @Resource、@Autowired、@Qualifier区别

    @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...

  4. @Autowired,@Resource,@Qualifier,@Primary,@Inject的作用和区别

    @Autowired注解的用法:可以用于构造器,方法,参数,字段进行属性注入,有一个required属性,默认是true,当改成false时,如果注入的属性在容器中不存在也不会报错@Resource该 ...

  5. @Autowired 与@Resource的区别(详细)

    参考:@Autowired 与@Resource的区别(详细) spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@Pos ...

  6. @Autowired 与@Resource的区别详解

    spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...

  7. 关于Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析

    1.Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service和 @Controller 其实这三个跟@Com ...

  8. java @Autowired与@Resource的区别

    @Autowired与@Resource的区别     1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认 ...

  9. Spring 注释 @Autowired 和@Resource 的区别

    Spring 注释 @Autowired 和@Resource 的区别 一. @Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上. 二. @Autowired ...

  10. @Autowired & @Resource 区别 & 解读@Bean

    一样     Autowired & @Resource 都可以用来Bean的注入,可以写在属性(字段)上.也可以写在setter方法上 不一样 1.来源不一样 @Autowired 由Spr ...

随机推荐

  1. Thread.yield( )方法

    Java线程中的Thread.yield( )方法,译为线程让步.顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行,注意是让自己或者其他线程运行 ...

  2. Golang内存模型

    Ref: https://golang.org/ref/mem 简介 golang内存模型,主要说明了如下问题.在一个goroutine中读取变量,而该变量是由其他goroutine赋值的,这种情况下 ...

  3. vue hash模式下微信分享后打开首页,三种完美解决方案

    微信分享功能给我们带来了很大的便利,使得基于微信开发出来的 H5 页面可以很好的通过微信平台进行传播.所以呢,基本上每个基于微信开发的 H5 都会集成微信分享功能.但是,前几天在对接微信分享 API ...

  4. python上获得随机字符

    import random import string print(string.ascii_letters) # 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO ...

  5. Apache httpd.conf配置文件 3(虚拟主机)

    ### Section 3: Virtual Hosts 第三部分 虚拟主机 注意:在使用虚拟主机前,请先检查  http.conf 的 辅助配置文件httpd-vhosts.conf 是否注释 # ...

  6. log4j2 springboot 特点与使用方法

    Apache Log4j2 is an upgrade to Log4j that provides significant improvements over its predecessor, Lo ...

  7. jsessionid與cookie關係的理解

    本地測試地址為http://localhost/TEST/login.jsf 當瀏覽器打開cookie時,瀏覽器第一次與服務器建立連接,會創建一個session,並生成一個id即jsessionid, ...

  8. Nginx是什么 ? 能干嘛 ?

    学习博客:https://blog.csdn.net/forezp/article/details/87887507 学习博客:https://blog.csdn.net/qq_29677867/ar ...

  9. js 递归总结

    1.根据子id 递归查找所有父级 id  主要用于vue  element 中 Cascader 级联选择器展示 在编辑中回显默认展示 tree 数据 var arr = [{ "label ...

  10. backgroud图片充满元素的方法

    background-image: url("img/headimg.png"); height: 219px; background-size: 100% 100%; backg ...