Spring中的@Autowired

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

    推荐阅读