Announcement Announcement Module
Collapse
No announcement yet.
cannnot autowire beans registered by registerBeanDefinition() Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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.

    Comment


    • #3
      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.

      Comment


      • #4
        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.

        Comment


        • #5
          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.

          Comment

          Working...
          X