Results 1 to 5 of 5

Thread: cannnot autowire beans registered by registerBeanDefinition()

  1. #1
    Join Date
    Feb 2012
    Posts
    7

    Default cannnot autowire beans registered by registerBeanDefinition()

    I have an ApplicationContextAware factory bean that generates proxy beans of a given list of interfaces in the post-construct method:

    Code:
    @PostConstruct
    public void generateProxy() {
      ...
      applicationContext.getBeanFactory().registerBeanDefinition("myProxy", ...);
    }
    The generated proxy works as expected when it is injected into other beans explicitly:

    Code:
    <bean ... depends-on="myFactory">
    	<property name="myIntrfc" ref="myProxy"/>
    <bean/>
    However, if the property myIntrfc is set to autowired, Spring complains "no matching bean of type MyIntrfc". I guess it is due to the order: autowiring is done before post-construct of the depends-on bean. Am I correct and any way to change the order?

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Creating bean definitions should be done before this so instead of a factorybean I suggest using a BeanFactoryPostProcessor that also makes your proxies/bean definitions registered like all the other and you don't have these issues.

    It BTW has nothing to do with ordering but the fact that you are probably wrongly using the FactoryBean, it probably doesn't return the correct type so spring doesn't know that your factory bean is creating instances of class X.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Feb 2012
    Posts
    7

    Default

    Thanks Marten. My factory is actually not a FactoryBean. FactoryBean makes a bean of a known type. My factory makes multiple beans of types (specified by List of java.lang.Class) that are unknown at compile time.

    BeanFactoryPostProcessor is surely more appropriate than ApplicationContextAware + @PostConstruct. But it still doesn't work after rewrite. My factory makes JDK proxy:

    Code:
    public <T> T getProxy(Class<T> intrfc) {
    	return (T) Proxy.newProxyInstance(intrfc.getClassLoader(), new Class<?>[]{intrfc}, myInvocationHandler);
    }
    The bean definitions:
    Code:
    for (Class<?> clazz : classes) {
    	RootBeanDefinition beanDefinition = new RootBeanDefinition();
    	beanDefinition.setFactoryBeanName(/*factory's bean name*/);
    	beanDefinition.setFactoryMethodName("getProxy");
    	ConstructorArgumentValues constArgs = new ConstructorArgumentValues();
    	constArgs.addIndexedArgumentValue(0, clazz);
    	beanDefinition.setConstructorArgumentValues(constArgs);
    	beanDefinition.setAutowireCandidate(true);
    	beanFactory.registerBeanDefinition(/*proxy's bean name*/, beanDefinition);
    }
    When the proxy is injected explicity (ref="myProxy"), the factory method (getProxy) is invoked. For autowiring, it is not invoked before Spring complains "no matching bean of type ...". I guess it is necessary to specify in the bean definition that the proxy is an instance of the desired interface, but I can't find the API to do so.

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Instead of creating your own proxy thingy I suggest registereing a ProxyFactoryBean which is a Spring FactoryBean which should implement a getClass method which should work with your construct.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Feb 2012
    Posts
    7

    Default

    Thanks Marten. FactoryBean works. The problem with bean-definition with factory-method is that Spring is unable to determine the return type because getProxy() is generic.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •