好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解Spring @Autowired 注入小技巧

今天和同事讨论到spring自动 注入 时,发现有这么一段代码特别地困惑,当然大致的原理还是可以理解的,只不过以前从来没有这么用过。想到未来可能会用到,或者未来看别人写的代码时不至于花时间解决同样的困惑,所以小编还是觉得有必要研究记录一下。

一、同一类型注入多次为同一实例

首先让我们先看下这段代码是什么?

?

1

2

3

4

5

@autowired

private xiaoming xiaoming;

 

@autowired

private xiaoming wanger;

xiaoming.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package com.example.demo.beans.impl;

 

import org.springframework.stereotype.service;

 

/**

  *

  * the class xiaoming.

  *

  * description:小明

  *

  * @author: huangjiawei

  * @since: 2018年7月23日

  * @version: $revision$ $date$ $lastchangedby$

  *

  */

@service

public class xiaoming {

 

  public void printname() {

   system.err.println( "小明" );

  }

}

我们都知道 @autowired 可以根据类型( type )进行自动注入,并且默认注入的bean为单例( singleton )的,那么我们可能会问,上面注入两次不会重复吗?答案是肯定的。而且每次注入的实例都是同一个实例。下面我们简单验证下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@restcontroller

public class mycontroller {

 

  @autowired

  private xiaoming xiaoming;

 

  @autowired

  private xiaoming wanger;

 

  @requestmapping (value = "/test.json" , method = requestmethod.get)

  public string test() {

   system.err.println(xiaoming);

   system.err.println(wanger);

   return "hello" ;

  }

}

调用上面的接口之后,将输出下面内容,可以看出两者为同一实例。

com.example.demo.beans.impl.xiaoming@6afd4ce9
com.example.demo.beans.impl.xiaoming@6afd4ce9

二、注入接口类型实例

如果我们要注入的类型声明为一个接口类型,而且该接口有1个以上的实现类,那么下面这段代码还能够正常运行吗?我们假设 student 为接口, wanger 和 xiaoming 为两个实现类。

?

1

2

3

4

5

@autowired

private student stu1;

 

@autowired

private student stu2;

?

1

2

@service

public class xiaoming implements student {

?

1

2

@service

public class wanger implements student {

答案是上面的代码不能正常运行,而且spring 还启动报错了,原因是spring想为 student 注入一个单例的实例,但在注入的过程中意外地发现两个,所以报错,具体错误信息如下:

field stu1 in com.example.demo.controller.mycontroller required a single bean, but 2 were found:
 - wanger: defined in file [c:\users\huangjiawei\desktop\demo\target\classes\com\example\demo\beans\impl\wanger.class]
 - xiaoming: defined in file [c:\users\huangjiawei\desktop\demo\target\classes\com\example\demo\beans\impl\xiaoming.class]

那该怎么弄才行呢?一般思路我们会想到为每个实现类分配一个id值,结果就有了下面的代码:

?

1

2

3

4

5

@autowired

private student stu1;

 

@autowired

private student stu2;

?

1

2

@service ( "stu1" )

public class xiaoming implements student {

?

1

2

@service ( "stu2" )

public class wanger implements student {

做完上面的配置之后,spring就会根据字段名称默认去bean工厂找相应的bean进行注入,注意名称不能够随便取的,要和注入的属性名一致。

三、总结

1、同一类型可以使用 @autowired 注入多次,并且所有注入的实例都是同一个实例; 2、当对接口进行注入时,应该为每个实现类指明相应的id,则spring将报错;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://juejin.im/post/5b557331e51d45191c7e64d2

查看更多关于详解Spring @Autowired 注入小技巧的详细内容...

  阅读:50次