Reputation: 41
Correcting what I've posted:
In my java class I have:
@Autowired
@Qualifier("customerProviderExec")
private DefaultCustomerProvider customerProvider;
And in my context configuration XML
<bean id="customerProviderExec" class="my.package.DefaultCustomerProviderExecutor">
<property name="defaultCustomerProviderService" ref="customerProviderImpl" />
</bean>
<bean id="testCustomerProviderImpl" class="my.package.DefaultCustomerProviderTest">
<property name="customerProviderImpl" ref="customerProviderImpl" />
</bean>
<bean id="customerProviderImpl" class="my.package.DefaultCustomerProviderImpl">
...
</bean>
Important: The class DefaultCustomerProviderImpl implements DefaultCustomerProvider
When I try to execute in my Java class:
DefaultCustomerProviderExecutor executor = (DefaultCustomerProviderExecutor)this.getCustomerProvider();
return (DefaultCustomerProviderImpl) executor.getDefaultCustomerProviderService();
I get the error:
Caused by: java.lang.ClassCastException: $Proxy17 cannot be cast to my.package.DefaultCustomerProviderImpl
Has someone been throug this?
Upvotes: 1
Views: 555
Reputation: 40256
Spring will create a proxy around the interface you are supplying and use the my.package.DefaultCustomerProviderImpl
as the backing implementation. You will have to program to the interface and not the implementation.
It looks something like this if you were to code it yourself
public class DefaultCustomerProviderProxy implements DefaultCustomerProvider {
DefaultCustomerProvider delegate;//DefaultCustomerProviderImpl customerProviderImpl instance
@Override
public void interfaceMethod1(){
doSomeSpringStuffMaybeOpenTransaction();
delegate.interfaceMethod1();
doSomeSringStuffMaybeCloseTransaction();
}
}
In practice its actually done much more differently using Java Proxy
So you can see why you cannot cast to the implementation you define.
Upvotes: 3
Reputation: 1567
There is no need to type cast to DefaultCustomerProviderImpl
. This defeats the very purpose of interface development. Your code should be like this
DefaultCustomerProvider customer = this.getCustomerProviderImpl();
The Spring environment will make sure that right implementation class is injected at run-time.
Upvotes: 0
Reputation: 2243
One thing not related to your question
I am not very well aware of Spring annotations but if the one you have used for autowiring is correct you should never had the need of explicitly specifying the customerProviderImpl property in bean with id testCustomerProviderImpl. One of these two should be required.
Coming to your question, never have encountered situation like this but may the point raised above has the capability of being a culprit.
If you still run in to the same issue, use Proxy design pattern to resolve the issue.
Upvotes: 0