This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Inject4Spring - opposite direction of references injection

Jun 8th, 2008, 10:22 AM

Inject4Spring is a small Open Source library that extends base functionality of Spring framework by allowing wiring beans in Spring context using "opposite" direction comparing to standard Spring approach.

If we have, say, two beans defined within context, and first bean refers to other bean, that reference should be described within bean context configuration XML directly as part of referring bean definition. This is casual and "natural" Spring way of defining dependencies between beans.

However, for some types of applications that approach does not work. The major drawback of it is as follows: during definition of referring bean it's assumed that the name of bean to which it refers is known.

Therefore, to obtain truly extensible applications, we need to have ability to "extend" existing content of Spring context.

In other words, instead of having reference on bean that "REFERS" to another bean, with such notation we are able to specify that reference on bean declaration which is actually "REFERENDED" by another bean.

Well, that's just very short overview. Please refer to my blog for more details about that approach and for downloading Inject4Spring...

Oops, it seems that forum does not allow me to post URL... That's really sad...
Ok, sorry for that - you can more about Inject4Spring here

Comment

Ok, that's pretty simple - let's imagine we have some application (in general, non-web one) that is built using plugins scheme. And ones is based on Spring.

Obviously, we have some basic logic encapsulated in beans stored in "core" Spring context.

Later, we'd like to extend that core functionality by one provided by plugins (and please mind that it could be thirdparty plugins that are developed after application release).

And here we have weird issue - it's not clear how to extend bean definition that is already placed in core spring contex...

Just as example - it's slightly artificial, yet should highlight the idea - what if we have some UI place that shows dynamic list of actions. Actions are ordinary beans and are defined in Spring context.

There is appropriate provider for that actions which contains list of actions that should be shown. Without modification of original context, we simply unable to add another bean to that list to show additional action delivered by plugin.

And that's why such an "opposite" direction of injection (from plugin to core context) is necessary for such king of applications...

Ok, that's pretty simple - let's imagine we have some application (in general, non-web one) that is built using plugins scheme. And ones is based on Spring.

Obviously, we have some basic logic encapsulated in beans stored in "core" Spring context.

Later, we'd like to extend that core functionality by one provided by plugins (and please mind that it could be thirdparty plugins that are developed after application release).

And here we have weird issue - it's not clear how to extend bean definition that is already placed in core spring contex...

Just as example - it's slightly artificial, yet should highlight the idea - what if we have some UI place that shows dynamic list of actions. Actions are ordinary beans and are defined in Spring context.

There is appropriate provider for that actions which contains list of actions that should be shown. Without modification of original context, we simply unable to add another bean to that list to show additional action delivered by plugin.

And that's why such an "opposite" direction of injection (from plugin to core context) is necessary for such king of applications...

Comment

Context may have several beans with same id, last wins.
so I just add file with provider (or list) redifinition(s) at the end of context files list. That's all. No injection in the opposite direction.

Well, in general, yes - if bean overriding is allowed for context. For simple cases such approach may work.

However, it does not solve the problem if 2 independent plugins provide functionality that should extend core one (consider example with list - one plugin adds 2 actions and another plugin adds ANOTHER two actions) - it's simply not clear which declaration should be the last one (and, of course, using approach with complete re-declaration, these plugins are tightly coupled).

Comment

Well, in general, yes - if bean overriding is allowed for context. For simple cases such approach may work.

However, it does not solve the problem if 2 independent plugins provide functionality that should extend core one (consider example with list - one plugin adds 2 actions and another plugin adds ANOTHER two actions) - it's simply not clear which declaration should be the last one (and, of course, using approach with complete re-declaration, these plugins are tightly coupled).

Regards,
Andrew

Comment

Hm... not sure that I understand how that could be done - as far as I know, merging of collections works for parent-child bean definitions, not for beans overriding... Or probably I miss something? Could you please expand that?

Comment

And yet another option - using factory bean to build list definition - this factory bean may collect from context all beans that implement e.g. Plugin interface and
build list of them. Yes. implementation of such factory bean requires some lines of Java code, but only few.

So for almost every situation problem may be solved by means of already existing Spring functionality.

Comment

Sure, but if you aticipate that some functionality would be expanded by plugins,
you may always define orginal list as abstract bean, but inject its concrete child. But yes, it seems that in this case at least one plugin need to know about presence of other. Not very good indeed.

Hm... not sure that I understand how that could be done - as far as I know, merging of collections works for parent-child bean definitions, not for beans overriding... Or probably I miss something? Could you please expand that?

Comment

And yet another option - using factory bean to build list definition - this factory bean may collect from context all beans that implement e.g. Plugin interface and
build list of them. Yes. implementation of such factory bean requires some lines of Java code, but only few.

What if we need to areas where we need to show actions? It seems that there should be logic in factory that which accept only specific ones And for different place you'll still need custom logic... and so on. I suppose it's simpler to have some reusable mechanism for that.

So for almost every situation problem may be solved by means of already existing Spring functionality.

Yes, in general, that's possible... but what for? I don't think it's practical to consider Spring as closed ecosystem - all it internal architecture was created with assumption of further extension (I mean protected methods, factory methods, internal factories and policies) and it's pretty easy to customize or expand it as necessary (of course, if that's practical).

I simply suppose that for tasks we've solved, that approach supported by Inject4Spring was pretty convenient - sure thing, it's not a silver bullet and it will be hardly needed for all applications.

What if we need to areas where we need to show actions? It seems that there should be logic in factory that which accept only specific ones And for different place you'll still need custom logic... and so on. I suppose it's simpler to have some reusable mechanism for that.

Yes, in general, that's possible... but what for? I don't think it's practical to consider Spring as closed ecosystem - all it internal architecture was created with assumption of further extension (I mean protected methods, factory methods, internal factories and policies) and it's pretty easy to customize or expand it as necessary (of course, if that's practical).

I simply suppose that for tasks we've solved, that approach supported by Inject4Spring was pretty convenient - sure thing, it's not a silver bullet and it will be hardly needed for all applications.