Migrating from spring xml configuration to @Configuration (servlet 3.0) with bean references causes BeanNotOfRequiredTypeException

StackOverflow https://stackoverflow.com/questions/23080114

Question

I am migrating from xml based spring configuration to "class" based configuration using the corresponding @Configuration annotation.

I came across the following problem: I want to create a new bean, which has a reference to another (service) bean. Therefore I autowired this class to set this reference during bean creation. My configuration class looks as follows:

@Configuration
@ComponentScan(basePackages = {"com.akme"})
public class ApplicationContext {

    @Resource
    private StorageManagerBean storageManagerBean;

    @Bean(name = "/storageManager")
    public HessianServiceExporter storageManager() {
        HessianServiceExporter hessianServiceExporter = new HessianServiceExporter();
        hessianServiceExporter.setServiceInterface(StorageManager.class);
        hessianServiceExporter.setService(storageManagerBean);
        return hessianServiceExporter;
    }
}

But this doesn't work, because the causes a BeanNotOfRequiredTypeException exception during startup.

Bean named 'storageManagerBean' must be of type [com.akme.StorageManagerBean], but was actually of type [com.sun.proxy.$Proxy20]

The StorageManagerBean is annotated with an @Service annotation. And the xml based configuration worked as expected:

<bean name="/storageManager" class="org.springframework.remoting.caucho.HessianServiceExporter">
    <property name="service" ref="storageManagerBean"/>
    <property name="serviceInterface" value="com.akme.StorageManager"/>
</bean>

So, I've no idea what I am doing wrong and why spring tries to auto wired a proxy class.

I appreciate your help.

Best regards, Daniel

Was it helpful?

Solution

When using Spring Remoting it will create proxies for the remote beans. This is to hide the complexity of the used technology. So in your case it will construct a proxy which implements the StorageManager interface and as such it will create a proxy implementing that interface.

Now that not only goes for Spring Remoting but basically for Spring AOP as well, AOP is applied with proxies (as explained in the reference guide). So I suspect that you have transactions around your StorageManagerBean which, by default, leads to a JDK Dynamic proxy. This proxy is, again, interface based.

In short inject a StoreManager instance instead of a StoreManagerBean instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top