从Spring 2.5 开始,自动装配功能进行了多次改进,可以通过@Autowired或者@Resource注解一个设值方法,构造字段,属性甚至任意方法自动装配特定的属性。
为了要求Spring 自动装配具有@Autowired或者@Resource注解的属性,必须在IOC容器中注册一个AutowiredAnnotationBeanPostProcessor实例。在上下文中什么实例:
写道
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
也可以在bean的配置文件中包含<context:annotation-config/>元素。或者是
写道
<context:component-scan base-package="*"></context:component-scan>
默认情况下所有带@Autowired的属性都是必须的,如果没有找到匹配的Bean就会抛出如下异常
写道
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sequenceGenerator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private SpringInAction.IOC.PrefixGenerator SpringInAction.IOC.SequenceGeneratorImpl.prefixGenerator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [SpringInAction.IOC.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
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)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at SpringInAction.IOC.App.main(App.java:14)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private SpringInAction.IOC.PrefixGenerator SpringInAction.IOC.SequenceGeneratorImpl.prefixGenerator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [SpringInAction.IOC.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 13 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [SpringInAction.IOC.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:947)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485)
... 15 more
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)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at SpringInAction.IOC.App.main(App.java:14)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private SpringInAction.IOC.PrefixGenerator SpringInAction.IOC.SequenceGeneratorImpl.prefixGenerator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [SpringInAction.IOC.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 13 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [SpringInAction.IOC.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:947)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485)
... 15 more
如果你希望某个属性是可选的可以将@Autowired的required属性设置为false 。这样当Spring 找不到匹配的bean之后,将不设置该属性。
写道
@Autowired(required=false)
private PrefixGenerator prefixGenerator;
private PrefixGenerator prefixGenerator;
运行结果:
ABC10000A
ABC10001A
默认情况下,按照类型自动装配在IOC容器中有超过一个类型兼容性的Bean时无效,但是Spring 允许指定一个候选Bean 这个Bean的名称在@Qulifier注解中提供。