Spring中的@Autowired

来源:互联网 发布:win32编程 u盘 编辑:程序博客网 时间:2024/05/01 01:19

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


可以看一个实际的问题:

代码中的注释装配

@Servicepublic class MailNotifServiceImpl extends AbstractThreadPool<MailNotifTask> implements MailNotifService {@Autowiredprivate JavaMailSender mailSender;
xml文件中的配置

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">         <property name="host" value="smtp.163.com"/> 

运行异常描述

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容器也不知道该用哪个实现类来注入,抛出异常


解决方法:以下三种方式均可以解决上面问题

1,将@Autowired换成@Resource,即

@Resourceprivate JavaMailSender mailSender;

2,将属性类型换成具体的实现类(虽然能解决问题,但失去了Ioc的灵活性),即

@Autowiredprivate 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)进行匹配,如果匹配则自动装配;