Spring注解的(List&Map)特殊注入功能
一、先看一个示例演示: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中也发现相关说明。
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)特殊注入功能的更多相关文章
- spring注解不支持静态变量注入
spring注解不支持静态变量注入:今天敲代码 自动配置 配置: Animal.java package study01_autoconfig.beanConfig; import org.spri ...
- spring注解(Component、依赖注入、生命周期、作用域)
1.注解 注解就是一个类,使用@加上注解名称,开发中可以使用注解取代配置文件 2.@Component 取代<bean class="">,@Component 取代 ...
- 使用spring注解——定义bean和自动注入
对于java bean的定义和依赖配置,使用xml文件真心是不方便. 今天学习如何用注解,解决bean的定义和注入. 常用注解: 1.自动注入:@Resources,@Autowired 2.Bean ...
- Spring注解问题,[action中注入service失败
pring-mvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- Spring-Context的注解实现依赖注入功能
使用Spring-Context的注解实现依赖注入功能. Demo要点: 本例子中主要使用Annotation功能来实现对MoviceService的注入.我们将Cinema.java的头部标注为@C ...
- 使用Spring注解注入属性
本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifier,@Pos ...
- SpringBoot的注解注入功能移植到.Net平台(开源)
*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...
- 【Spring】的【Bean】管理(注解)【四个相同功能的注解】
[Spring]的[Bean]管理(注解)[四个相同功能的注解] 注解:代码里面特殊的标记,使用注解也可以完成一些相关的功能. 注解写法:@注解名称(属性名称=属性值) 注解使用在类.方法.属性上面 ...
- spring注解方式在一个普通的java类里面注入dao
spring注解方式在一个普通的java类里面注入dao @Repositorypublic class BaseDaoImpl implements BaseDao {这是我的dao如果在servi ...
随机推荐
- 洛谷P1352 没有上司的舞会
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
- iOS APP 的生命周期
1.在手机桌面上点击APP图标 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDi ...
- MFC中的双缓冲技术(解决绘图闪烁问题)
转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...
- android 获得电池状态
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
- Linux网络编程简单示例
linux 网络编程是通过socket(套接字)接口实现,Socket是一种文件描述符,socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭& ...
- aSmack连接server异常smack.SmackException$ ConnectionException thrown by XMPPConnection.connect();
以下是我在研究asmack4.0出现的异常 06-17 12:02:56.924: W/System.err(10622): org.jivesoftware.smack.SmackException ...
- [Servlet&JSP] 标准标签
在JSP的规范中提供了一些标准标签(Standard Tag),全部的容器都支持这些标签,它能够协助编写JSP时降低Scriptlet的使用. 全部的标准标签都使用jsp:作为前置.这些标准标签是在J ...
- 带GPG签名的Git tag
原文地址http://airk000.github.io/git/2013/09/30/git-tag-with-gpg-key Git tag ###Tag用来做什么? Tag即标签,用以给项目仓储 ...
- 读写锁(pthread)
读写锁: 用于对于某个给定资源的共享访问,而不是像互斥锁那样,将所有试图进入临界区的线程都阻塞住 相关内容: 线程互斥锁 分配规则:(写独占,读共享) 1.只要没有线程持有某个给定的读写锁用于写,那么 ...
- 项目Beta冲刺(团队1/7)
项目Beta冲刺(团队1/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...