一、先看一个示例演示:spring注解的一个特殊的注入功能。

首先,是定义一个接口,3个实现类。

public interface GreetService {

    public String sayHello(String name);

}
@Service("china")
public class ChinaGreetServiceImpl implements GreetService { @Override
public String sayHello(String name) {
return "你好";
} }
@Service("japan")
public class JapanGreetServiceImpl implements GreetService { @Override
public String sayHello(String name) {
return "亚麻得";
} }
@Service("usa")
public class UsaGreetServiceImpl2 implements GreetService { @Override
public String sayHello(String name) {
return "hello";
} }

下面看到代码中有直接注入一个List和一个Map的。示例代码如下:

GreetController代码:

@RestController
@RequestMapping("/greet")
public class GreetController { @Autowired
private List<GreetService> greetServiceList; @Autowired
private Map<String, GreetService> greetServiceMap; @RequestMapping(value = "/test/{id}", method = RequestMethod.GET)
public String getbook5(@ApiParam("id编号") @PathVariable("id") Long id) {
for (Map.Entry<String, GreetService> entry : greetServiceMap.entrySet()) {
System.out.println(entry.getValue().sayHello("" + id));
}
System.out.println("==list====");
for (GreetService greetService : greetServiceList) {
System.out.println(greetService.sayHello("" + id));
} return "" + id;
} }

最后在调试List的时候突然灵感一闪,如果只有一个对象那么List里面的值不就只有一个吗。于是开始测试验证,结果发现的确如此。当实例化一个GreetController之后,另外一个类采用泛型注入List,Spring竟然成功的将实例化的对象放入List之中。思路打开之后,针对Map的就更好说了。Spring会将service的名字作为key,对象作为value封装进入Map。

运行之后,访问http://127.0.0.1:8091/greet/test/1执行结果如下:

原来,在不知不觉中Spring已经帮我们做了很多事情,只是我们不知道而已。

二、@Autowired 注入集合类型

从spring-beans-4.3.14.RELEASE.jar的源码可以看看到如下:

在org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DependencyDescriptor, String, Set<String>, TypeConverter) 方法中发现了原因。

对于@Autowired声明的数组、集合类型,spring并不是根据beanName去找容器中对应的bean,而是把容器中所有类型与集合(数组)中元素类型相同的bean构造出一个对应集合,注入到目标bean中。对应到上问配置文件中,就是把容器中所有类型为java.lang.String的bean放到新建的Set中,然后注入到Manager bean中。也就是把resourcePackage和resourceLoaction这两个String注入了,导致上面的输出结果。

在spring reference中也发现相关说明。

@Autowired

If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to
the specific collection or map bean by unique name.
@Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, @Resource is supported only for fields and bean property setter methods with a single argument.
As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.

从上面的说明中找到解决办法就是注入集合类型不要使用@Autowired,而使用@Resource注解。同时Spring官方也是不推荐使用@Autowired的。

Spring注解的(List&Map)特殊注入功能的更多相关文章

  1. spring注解不支持静态变量注入

    spring注解不支持静态变量注入:今天敲代码  自动配置 配置: Animal.java package study01_autoconfig.beanConfig; import org.spri ...

  2. spring注解(Component、依赖注入、生命周期、作用域)

    1.注解 注解就是一个类,使用@加上注解名称,开发中可以使用注解取代配置文件 2.@Component 取代<bean  class="">,@Component 取代 ...

  3. 使用spring注解——定义bean和自动注入

    对于java bean的定义和依赖配置,使用xml文件真心是不方便. 今天学习如何用注解,解决bean的定义和注入. 常用注解: 1.自动注入:@Resources,@Autowired 2.Bean ...

  4. Spring注解问题,[action中注入service失败

    pring-mvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  5. Spring-Context的注解实现依赖注入功能

    使用Spring-Context的注解实现依赖注入功能. Demo要点: 本例子中主要使用Annotation功能来实现对MoviceService的注入.我们将Cinema.java的头部标注为@C ...

  6. 使用Spring注解注入属性

    本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifier,@Pos ...

  7. SpringBoot的注解注入功能移植到.Net平台(开源)

    *:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...

  8. 【Spring】的【Bean】管理(注解)【四个相同功能的注解】

    [Spring]的[Bean]管理(注解)[四个相同功能的注解] 注解:代码里面特殊的标记,使用注解也可以完成一些相关的功能. 注解写法:@注解名称(属性名称=属性值) 注解使用在类.方法.属性上面 ...

  9. spring注解方式在一个普通的java类里面注入dao

    spring注解方式在一个普通的java类里面注入dao @Repositorypublic class BaseDaoImpl implements BaseDao {这是我的dao如果在servi ...

随机推荐

  1. android 加一个按钮,退出程序

    package com.example.yanlei.yl; import android.graphics.Color; import android.support.v7.app.AppCompa ...

  2. Mysql 性能优化20个原则(2)

    5. 在Join表的时候使用相当类型的例,并将其索引 如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的.这样,MySQL内部会启动为你优化Join的SQL语句的机 ...

  3. expect实现无交互操作

    按两下tab linux总共2000个命令,,常用的200个命令. 只要文件改变了,MD5值就会变!

  4. Microsoft Dynamics CRM Server 2013软件安装要求

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveV9mMTIz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  5. Intel Active Management Technology

    http://en.wikipedia.org/wiki/Intel_Active_Management_Technology Intel Active Management Technology F ...

  6. dom get selector

    function realsQuery(element) { if(!element){ return ""; } var currentQuery=""; i ...

  7. IOS 获取设备本地音视频

    1.检索音视频 PHFetchOptions *allPhotosOptions; @property (nonatomic, strong) PHFetchResult *assetsFetchRe ...

  8. TinyXML:TiXmlNode

    TiXmlNode: 对应于DOM结构中的节点,是TinyXML中很重要的一个类,它继承自TiXmlBase TiXmlNode的友元类: friend class TiXmlDocument; fr ...

  9. Android 通过Application 传递数据

    </pre><pre> package com.example.ApplicationTest; import android.app.Application; /** * C ...

  10. 直播:中国HBase技术社区第一届MeetUp

    6月6日,由中国HBase技术社区组织,阿里云主办的中国第一届HBase Meetup将在北京举行,来自阿里.小米.滴滴.360等公司的各位大神会共同探讨HBase2.0的技术革新,HBase在国内各 ...