开发者

Injecting Annotated Bean into Regular Bean

开发者 https://www.devze.com 2023-01-04 07:14 出处:网络
AppContext.xml <bean id=\"myBean\" class=\"com.myapp.MyClass\"> <pro开发者_如何学Goperty ref=\"myService\"/>

AppContext.xml

<bean id="myBean" class="com.myapp.MyClass">
    <pro开发者_如何学Goperty ref="myService"/>
</bean>

MyService.java

@Service
public class MyService {
 ...
}

This will throw an exception stating that no bean can be found for property "myService", which I understand because it can't be found in the context files, but I can autowire that field in other spring managed beans, but I need to explicitly build the bean in my context because the POJO is not editable in the scope of my project.


Assuming you're already using the component classpath scanning, then you can give an explicit name to the component, rather than letting Spring auto-generate a name for you:

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

I haven't tested this, but I believe this is the case.


edit: After a bit of digging, the logic for determining the bean name is found in 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);
}

In other words, it tries to get an explicit bean name from the annotation(s), and failing that, it uses the default:

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

So yes, for an annotated class called MyService, the auto-generated bean name should indeed be myService, so your code should work.

Out of curiosity, what happens when you use @Component instead of @Service?


This should work, if you have

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

精彩评论

暂无评论...
验证码 换一张
取 消