2

I have a class annotated with @Configuration (let's call it StubConfiguration) which has a single method that is annotated with @Bean. This method returns a BeanFactoryPostProcessor implementation which is responsible for registering some beans. However, Spring is unable to resolve the beans this factory registers at runtime.

My assumption is that StubConfiguration is picked up by Spring's component scanning, the BeanFactoryPostProcessor is registered and then its postProcessBeanFactory() method is invoked, subsequently registering the beans I need.

Am I thinking about this incorrectly? How can I go about registering the beans that I need with my ApplicationContext using this post processing?

Tyler Treat
  • 14,640
  • 15
  • 80
  • 115
  • I think bean dependencies are probably determined before the `BeanFactoryPostProcessor` is invoked. Why register new beans with a post processor rather than create them directly from the `@Configuration` class? – matts Jun 19 '12 at 22:04
  • @matts: the post processor scans for and registers classes with a `@Stub` annotation. I can't think of an easy way to do this otherwise. – Tyler Treat Jun 19 '12 at 22:08
  • Does it do anything special with these stubs, or just tell Spring to add them to the application context and process them as normal? – matts Jun 19 '12 at 22:10
  • It simply finds them and registers them as singleton beans. – Tyler Treat Jun 19 '12 at 22:10

2 Answers2

0

If you're also using an XML app context to declare beans, you can tell Spring to do a component scan and treat @Stub as a Spring component annotation.

<context:component-scan base-package="your.base.package">
    <context:include-filter type="annotation" expression="your.stub.package.Stub"/>
</context:component-scan>

If you're only using an annotation config app context, check out this answer for a way to do it without XML.

Community
  • 1
  • 1
matts
  • 6,738
  • 1
  • 33
  • 50
  • I'm not sure if I completely follow. I have stub classes that are annotated with a `Stub` annotation that also contain the bean's name, e.g. `@Stub("myStub")`. Then later, for example, I might want to do something like `context.getBean("myStub", MyStub.class)`. – Tyler Treat Jun 19 '12 at 23:21
  • Is there an `applicationContext.xml` file (or other XML Spring context file) in your project that you have control over? The `component-scan` tag from above goes in there and tells Spring to search through the specified package and find classes with the specified annotation. Those classes are added as beans to the application context. (However, they would be named using the default naming strategy, which just uses the name of the class.) If you do not have a Spring application context file, this has to be done another way. – matts Jun 20 '12 at 14:50
  • This works, although it turns out I just needed to add the package the factory was in to the `base-package` of `component-scan`. Since it was in a separate package it wasn't being picked up by Spring. Adding that causes the beans to be registered during post processing. – Tyler Treat Jun 20 '12 at 23:01
0

What about making your @Stub annotation extend the @Component annotation? Like the @Service or @Repository.

You will have your beans scanned with the regular Spring context scanning, you can keep your custom annotation and you won't need to register manually your beans.

Example from @Service:

{@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any
     */
    String value() default "";

}}
moribvndvs
  • 42,191
  • 11
  • 135
  • 149
rodrigobartels
  • 821
  • 1
  • 9
  • 13
  • Unfortunately modifying `Stub` isn't really possible since I don't manage it, but even if it were, how would I go about loading the beans by their names? For example, if I annotated a stub bean with `@Stub("myStub")` as I mentioned in a comment on the other answer. My post processor factory currently registers the `Stub` beans using this name value so they can later be retrieved with it. – Tyler Treat Jun 20 '12 at 02:00