Spring中的@Autowired和@Resource都可以用来装配Bean,实现注释型的IOC(可以用在类的成员变量,构造函数或方法上),但两者却有一些区别:
1,@Autowired是Spring中的(import org.springframework.beans.factory.annotation.Autowired),而@Resource是Javax中的(import javax.annotation.Resource)
2,@Autowired按byType自动注入,而@Resource默认按 byName自动注入
可以参考: http://developer.51cto.com/art/201104/255395.htm
可以看一个实际的问题:
代码中的注释装配
@Service
public class MailNotifServiceImpl extends AbstractThreadPool implements MailNotifService { @Autowired
private JavaMailSender mailSender;
xml文件中的配置
运行异常描述
2012-11-27 20:21:44 org.apache.catalina.core.StandardContext listenerStart
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailNotifServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bubinglv.util.msgqueue.MessageSender com.bubinglv.notification.email.MailNotifServiceImpl.msgSender; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSender': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected org.springframework.amqp.core.Binding com.bubinglv.util.msgqueue.MessageSender.binding; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mailBinding' defined in ServletContext resource [/WEB-INF/spring/util/util-context.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: Could not convert constructor argument value of type [org.springframework.amqp.core.Queue] to required type [java.lang.String]: Failed to convert value of type 'org.springframework.amqp.core.Queue' to required type 'java.lang.String'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.amqp.core.Queue] to required type [java.lang.String]: no matching editors or conversion strategy found
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
问题原因:
因为@Autowired是按照Type方式进行依赖注入,而该例子中JavaMailSender是一个接口,并不是具体的实现类,所以Spring容器也不知道该用哪个实现类来注入,抛出异常
解决方法:以下三种方式均可以解决上面问题
【Spring中的@Autowired】1,将@Autowired换成@Resource,即
@Resource
private JavaMailSender mailSender;
2,将属性类型换成具体的实现类(虽然能解决问题,但失去了Ioc的灵活性),即
@Autowired
private JavaMailSenderImpl mailSender;
3,使用@Autowired和@Qualifier的结合
@Autowired
@Qualifier("mailSender")
private JavaMailSender mailSender;
故还是建议使用@Resource,补充一下@Resource装配的顺序
a.如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
b.如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
c.如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
d.如果既没有指定name,又没有指定type,则自动按照byName方式进行装配(见2); 如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配;
推荐阅读
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别
- jar|springboot项目打成jar包和war包,并部署(快速打包部署)
- 数据库|效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】)...
- java人生|35K 入职华为Java开发那天,我哭了(这 5 个月做的一切都值了)
- Java毕业设计项目实战篇|Java项目:在线嘿嘿网盘系统设计和实现(java+Springboot+ssm+mysql+maven)
- 微服务|微服务系列:服务发现与注册-----Eureka(面试突击!你想了解的Eureka都在这里.持续更新中......)
- java|ApplicationListener和SpringApplicationRunListener的联系
- Spring|SpringSecurity--自定义登录页面、注销登录配置
- 性能|性能工具之 Jmeter 通过 SpringBoot 工程启动
- 代码狂魔|Spring源码分析之IOC容器初始化流程