1

Is it possible to dynamically instantiate a bean in Spring using a factory?

I'd like to be able to instantiate some beans when a particular annotation is detected.

E.g.

@Retention ( RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE)
@Import(CreateFooRegistrar.class)
public @interface CreateFoo {
    String name();
}

public interface Foo {
    String getName();
    void setName(String name);
}

public class FooImpl implements Foo {
    ...
}

I can easily create beans directly using the concrete class:

public class CreateFooRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(CreateFoo.class.getName()));
        String fooName =  attributes.getString("name");
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FooImpl.class);
        builder.addPropertyValue("name", fooName);
        registry.registerBeanDefinition(fooName + "Foo", builder.getBeanDefinition());
    }
}

But is there any way I can create a bean using the returned object from a factory?

E.g.

public class FooFactory {
    public static FooImpl create(String name) {
        FooImpl foo = new FooImpl();
        foo.setName(name);
        return foo;
    }
}

The reason I ask is that all the beans I want to automatically create are typically instantiate via a factory. I don't own the factory code, so I'd prefer not to attempt to mimic its inner-workings myself.

Andy N
  • 1,238
  • 1
  • 12
  • 30
  • It's a bit unclear, but are you trying to create multiple beans of the same type `Foo`, with a different `name` parameter passed to each one? – Patrick Grimard Mar 16 '16 at 16:58
  • look here : [create-a-prototype-scoped-bean-with-runtime-arguments](http://stackoverflow.com/questions/22155832/spring-java-config-how-do-you-create-a-prototype-scoped-bean-with-runtime-argu) It contains exactly the answer to your problem. – Stefan Isele - prefabware.com Mar 16 '16 at 20:12
  • @Patrick - yes. In this example I would expect 2 `@CreateFoo` annotations to create 2 `Foo` beans. – Andy N Mar 17 '16 at 09:24
  • @Stefan - I don't want to use `@Bean`. I want to create them dynamically. I know my example shows a simple 1-to-1 relationship between the annotation and the bean I'm creating, but in reality the relationship will be 1-to-many. – Andy N Mar 17 '16 at 09:24
  • Where you going to apply `CreateFoo ` annotation? To the method of configuration or anywhere else? – Ken Bekov Mar 17 '16 at 10:21
  • The use-case I have in mind is a class-level annotation for configuring Spring to work with multiple databases (without all the boilerplate code and tight-coupling). [see here](https://github.com/spring-projects/spring-boot/issues/5401) – Andy N Mar 17 '16 at 10:43
  • So you're essentially talking about creating multiple `DataSource` beans? – Patrick Grimard Mar 17 '16 at 11:51
  • Not just DataSources, but JpaVendorAdapters, EntiryManagerFactories, basically all the stuff that spring would normally create for a single connection. I didn't want to cloud the issue with a lot of JPA specifics, so if I can figure out if it's possible to create a bean directly from a factory that'd be enough. Failing that I'll just extend the bean I want to create and add a static constructor which calls the factory method. I just don't want to because it's ugly! – Andy N Mar 18 '16 at 16:10

0 Answers0