一、先看一个示例演示: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. MySQL、Hive以及MySQL Connector/J安装过程

    MySQL安装 ①官网下载mysql-server(yum安装) wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch. ...

  2. File类 文件过滤器

    创建过滤器 package cn.zmh.File; import java.io.File; import java.io.FileFilter; // 实现FileFilter类的功能 publi ...

  3. HBase总结

    1.HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利用了Google ...

  4. 【Java TCP/IP Socket】深入剖析socket——数据传输的底层实现

    底层数据结构 如果不理解套接字的具体实现所关联的数据结构和底层协议的工作细节,就很难抓住网络编程的精妙之处,对于TCP套接字来说,更是如此.套接字所关联的底层的数据结构集包含了特定Socket实例所关 ...

  5. Spring中使用byName实现Beans自动装配

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/beans-auto-wiring/spring-autowiring-byname.html: 此 ...

  6. 【Todo】一些scala的实验 & 与Java的混合

    另外,如果要支持 java 和 scala混合build,可以看看这篇文章: http://www.cnblogs.com/yjmyzz/p/4694219.html Scala和Java实现Word ...

  7. [转]Linux统计代码行数

    wc -l *.c *.h 就可以知道当前目录下的所有c 和 h 文件的行数的详细信息.很不错 如果要递归,可以配合其他命令一起使用 当前目录及子目录: find . -name *.c |xargs ...

  8. ubuntu 添加和删除用户

    Without a home directory sudo useradd myuser With home directory sudo useradd -m myuser Then set the ...

  9. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part3

    Use custom Cypress command for reusable assertions We’re duplicating quite a few commands between th ...

  10. ShopMall

    https://github.com/KingsleyYau/ShopMall-Android https://github.com/KingsleyYau/ShopMall-iOS https:// ...