spauny
spauny

Reputation: 5096

Spring inheritance peculiarity

I have a question regarding Spring inheritance: Let's say I have a class (bean) BraveKnight that implements the interface Knight. After I declare this bean in the xml file with the id->knight, I'm trying to get a reference of the bean:

Knight knight = (Knight) context.getBean("knight"); 

This is the way it works. But why isn't possible to get the bean reference from the bean's name itself: BraveKnight (and why doesn't work with no interface at all)?

BraveKnight knight = (BraveKnight) context.getBean("knight"); 

Upvotes: 0

Views: 612

Answers (4)

goroncy
goroncy

Reputation: 2091

First of all please use:

public <T> T getBean(String name, Class<T> requiredType)

instead of:

public Object getBean(String name)

You will avoid this nasty class cast.

Secondly your question about why it is not working with no interface is a little bit unobvious. I guess you have some kind of problem getting BraveKnight when it is not implementing any interface at all. If you want do that you have to force Spring to use CGLIB instead of dynamic proxy mechanism. If you have a problem with ClassCastException though when casting your bean to BraveKnight it means that Spring used dynamic proxy and implemented a $Proxy0 class which is only implementing Knigh interface and does not extend BraveKnigh directly. Whatever your problem is please try to get to know CGLIB and JDK dynamic proxy mechanism better so that you will not be surprised next time what Spring will do in the future with your objects.
If that answer does not correspond to your problem please try to attach some more info, stack trace or explanation.

Upvotes: 2

Bitmap
Bitmap

Reputation: 12538

You can use BraveKnight as the bean name if that makes it simple and easier for you to understand your mappings. Craig Walls Spring In Action used Knight as the bean name to make it clear your mapping is calling an implementation of Knight.

Again it would not work with an interface because in java you cannot instantiate an interface. Mapping directly to Knight is exactly as doing;

Knight knight = new Knight(); // This is illegal

You will instantiate against the implementation of Knight to make it work, example:

Knight knight = new BraveKnight()//legal Implementation to Knight

This is the reason why the implementation was used as the mapping in the context file.

Upvotes: 0

danny.lesnik
danny.lesnik

Reputation: 18639

You can call been without interface from application context without any problem.

You will need interface only when you use AOP Proxy, in that case any object reference called not by interface will cause exception.

Upvotes: 0

duffymo
duffymo

Reputation: 308986

You are getting the bean using its name: "knight". You're using the Spring bean name as the key.

If your question is "Why can't I look up the bean using its type", the answer is that you can as long as there's only one bean of that type. It's called "autowiring". Spring can do it for you if you add annotations and a couple of required XML tags.

As for why it won't work with no interface, who said it didn't? You can wire concrete class types with Spring.

A better question would be "When and why should I prefer to use interfaces in Spring?" The answer is that designing to an interface for those cases where implementation is likely to change is a good practice whether you use Spring or not. It makes it possible for Spring to generate dynamic proxies as needed (e.g. adding transactions to persistence objects).

Upvotes: 1

Related Questions