将注释Bean注入常规Bean

时间:2010-06-17 14:06:02

标签: java spring dependency-injection

AppContext.xml

<bean id="myBean" class="com.myapp.MyClass">
    <property ref="myService"/>
</bean>

MyService.java

@Service
public class MyService {
 ...
}

这会抛出一个异常,说明没有找到属性“myService”的bean,我理解这是因为它无法在上下文文件中找到,但是我可以在其他Spring管理bean中自动装入该字段,但是我需要在我的上下文中显式构建bean,因为POJO在我的项目范围内是不可编辑的。

2 个答案:

答案 0 :(得分:3)

假设您已经在使用组件类路径扫描,那么您可以为组件指定一个显式名称,而不是让Spring为您自动生成一个名称:

@Service("myService")
public class MyService {
 ...
}

我没有对此进行过测试,但我相信情况确实如此。


编辑:经过一些挖掘,确定bean名称的逻辑可以在AnnotationBeanNameGenerator.generateBeanName()中找到。:

public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    if (definition instanceof AnnotatedBeanDefinition) {
        String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
        if (StringUtils.hasText(beanName)) {
            // Explicit bean name found.
            return beanName;
        }
    }
    // Fallback: generate a unique default bean name.
    return buildDefaultBeanName(definition);
}

换句话说,它试图从注释中获取一个显式的bean名称,如果失败,它会使用默认值:

protected String buildDefaultBeanName(BeanDefinition definition) {
    String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
    return Introspector.decapitalize(shortClassName);
}

所以是的,对于一个名为MyService的带注释的类,自动生成的bean名称确实应该是myService,因此您的代码应该可以工作。

出于好奇,当您使用@Component代替@Service时会发生什么?

答案 1 :(得分:1)

这应该有效,如果你有

<context:component-scan base-package="your.root.package" />