2
votes

I am using proxy beans with property-selectable transport protocol. My problem is that bean properties cannot be converted, but I really don't know why. This is the situation:

My property: service.protocol=rmi

<!-- This is the 'multiplexing' factory bean (using this because properties
cannot be used in bean names and aliases -->

   <bean name="dbFormGenWindowComponent" 
  class="org.springframework.beans.factory.config.BeanReferenceFactoryBean">
  <property name="targetBeanName" value="dbFormGenWindowComponent-${service.protocol}invoker" />
 </bean>

<!-- Here are the service invoker beans with two protocols: -->

  <bean name="dbFormGenWindowComponent-rmiinvoker" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
 <property name="serviceUrl" value="${ringwindow.serviceURL.rmi}/${ringwindow.service.name}-dbFormGenWindowComponent"/>
 <property name="serviceInterface" value="foo.bar.service.formgen.windows.FormGenWindowComponent" />
 <property name="lookupStubOnStartup" value="false"/>
  </bean>

The exception on startup is:

org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy541] to required type [foo.bar.service.formgen.windows.FormGenWindowComponent] for property 'formGenWindowComponent'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy541] to required type [foo.bar.service.formgen.windows.FormGenWindowComponent] for property 'formGenWindowComponent': no matching editors or conversion strategy found

I think nested factory beans should work fine. Do you have any idea how to get this work?

1

1 Answers

3
votes

This usually happens when you have defined your injection point types to be concrete classes, rather than interfaces, but you are proxying based on interface. For example:

public interface Foo { .. }
public class FooImpl { .. } // this is declared as bean

public class Bar {
    private FooImpl foo; // this fails
    private Foo foo; // correct way
}

In the case of factory beans this may be due to the factory bean's return type being defined as a concrete class. If you can't change anything in the classes, you can configure spring to use cglib-proxying, by:

  • <aop:scoped-proxy> - inside a bean definition - this will configure proxies of the bean
  • <aop:aspectj-autoproxy proxy-target-class="true"> - changes this globally