Reputation: 5514
Given the following classes:
package com.acme;
public class Foo {
private Bar bar;
public void setBar(Bar newBar) {
this.bar = newBar;
}
}
@AcmeService
public interface Bar {}
and a Spring configuration file of:
<beans>
<bean id="foo" class="com.acme.Foo">
<property name="bar" ref="bar" />
</bean>
</beans>
when Spring's configuration phase runs, is it possible to do the following?
I was initially drawn to BeanPostProcessor and BeanFactoryPostProcessor as a means to implement this, although upon reading the documentation I did not see an obvious way of doing precisely what I want.
In case you're wondering, the underlying use case is that I want to:
I have all of that working except for the whole "dynamically generate proxies" bit. Currently I have empty implementations of my service interfaces defined in my context file just so they can be injected and advised - but I'd rather not have so many empty interface classes generated and checked in. And lastly, I assume I need to generate these proxies as I do not know how to advise attempted invocations on null dependencies.
Upvotes: 4
Views: 2009
Reputation: 403441
OK, there's a number of things in here to talk about.
Firstly, I don't think you'll be able to do exactly what you're asking. In particular, if you have <property name="bar" ref="bar"/>
and there is no bean definition for bar
, the bean initialization will fail, and I don't think you can intercept that easily. You could, of course, write your own subclass of the BeanFactory
itself, but that's not something to be taken lightly.
The closest existing mechanism to what you're asking for is auto-wiring. Take a look at AutowiredAnnotationBeanPostProcessor. You could use this as a guide for writing your own BeanPostProcessor
which looks at every bean as it's instantiated by the container, looking for properties which are of types which in turn have the @AcmeService
annotation. When it finds one, it can generate a proxy for that type and inject it.
That brings us on to the proxy generation itself. The place to look for that is ProxyFactory. This allows you to generate objects at runtime that implement any interface or extend any class, whilst attaching advisors/interceptors. These interceptors can do all the work - the proxy doesn't have to have anything "behind" it if you don't want to.
With this approach, you wouldn't need the "hanging" <property name="bar" ref="bar"/>
entry in your config - the presence of the property in Foo
would be enough to trigger the process.
Upvotes: 2