1

I have a set of instances of FactoryBean which are of type MyFactoryBean. The constructor takes a Class<?> and uses that to determine what to return from getObject():

public class MyFactoryBean implements FactoryBean {

    private final Class<?> type;

    public MyFactoryBean(Class<?> type) {
        this.type = type;
    }

    @Override
    public Object getObject() throws Exception {
        return null; // Obviously I return something here rather than null!
    }

    @Override
    public Class<?> getObjectType() {
        return type;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

My end result is to control what is returned when an instance of type passed to the constructor of the MyFactoryBean is requested from the context.

I can register them with my context like this:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getBeanFactory().registerSingleton(..., ...);

But it doesn't feel right, and autowiring doesn't work. How do I register these with my context?


EDIT: for the autowiring, I have noted Sean Patrick Floyd response here: How to get beans created by FactoryBean spring managed? but this still doesn't answer my question.

Community
  • 1
  • 1
Cheetah
  • 13,785
  • 31
  • 106
  • 190

2 Answers2

2

I created this solution in the end, but I am not sure whether its the best or not:

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.addBeanFactoryPostProcessor(new BeanDefinitionRegistryPostProcessor() {

        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            ConstructorArgumentValues cav = new ConstructorArgumentValues();
            cav.addGenericArgumentValue(MyClass.class);

            RootBeanDefinition bean = new RootBeanDefinition(MyFactoryBean.class, cav, null);
            AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();

            registry.registerBeanDefinition(generator.generateBeanName(bean, registry), bean);
        }

        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }
    });
Cheetah
  • 13,785
  • 31
  • 106
  • 190
0

Take a look on the following discussion: How to inject dependencies into a self-instantiated object in Spring?

I believe that this is exactly what you need: use AutowireCapableBeanFactory.

Community
  • 1
  • 1
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • How do I register that `AutowireCapableBeanFactory` with the `AnnotationConfigApplicationContext `? – Cheetah Sep 03 '14 at 16:23
  • You should create your bean that will live in Spring context, inject `AutowireCapableBeanFactory` into it and use it to create other instances programmatically. These instances will be autowired if you use code similar to one that I referenced. – AlexR Sep 04 '14 at 07:12