views:

65

answers:

2

AppContext.xml

<bean id="myBean" class="com.myapp.MyClass">
    <property 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.

+1  A: 

This should work, if you have

<context:component-scan base-package="your.root.package" />
Bozho
I've gotten things to work, but I'm not exactly sure how, I'll have to spend a bit more time investigating, but I will come back to this and choose and answer soon
walnutmon
+3  A: 

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?

skaffman
won't the auto-generated name be the lower-case name of the class?
Bozho
@Bozho: I don't think so, no. When you use `<bean class="A.B">` with no `id`, the auto-generated name is something like `B#0`, and I assume the same applies to the auto-scanned components.
skaffman
it's not the same scenario, because there can't be another annotated bean of the same class
Bozho
@Bozho: Quite right. See edit.
skaffman