How to Manually Inject a Wicket SpringBean dependency
Have you ever got a problem with Dependency Injection when dealing with non-component classes in Wicket ?
Let me explain more clearly:
Nearly all Spring-enabled Wicket developers know that, If you want to bind your component to another object (let’s say, a business component), you should use the wicket @SpringBean annotation instead of the Spring “@Autowired” one.. That’s because the Wicket annotation will return a lightweight serializable proxy, ready to be persisted along with the entire component graph to which it is attached, without getting the risk to serialize the entire Spring Context along with it.
public class ModianoPanel extends Panel
implements IEventSubscriptionObserver,
IEditModeHolder {
private static Logger log = Logger.getLogger( ModianoPanel.class );
@SpringBean( name="ApplicationService" )
protected IApplicationService applicationService;
@SpringBean( name="CoreReadOnlyService" )
protected IReadOnlyService readOnlyService;
....
}
Ok, but what will you do when you want to bind an object to a, let’s say, helper class that is not a Wicket component ? you generally resort to the good old @Autowired Spring annotation, because it’s not your intention to serialize that helper class with your component graph..
public class PatentFileHelper extends FileManagementHelper
{
@Autowired
@Qualifier(value="CoreReadOnlyService")
private IReadOnlyService ros;
...
}
That’s good. But, alas, It happens to often that, sooner or later, a reference to your helper class will be held inside a Wicket component.. in that case, you’ll find yourself with a good load of warning messages from Wicket saying that your component graph is not anymore serializable..
The apparent solution is to simply use @SpringBean instead of @Autowired but it SEEMS that SOMETIMES this Wicket annotation does not initialize your dependency.. if this happens, consider to inject the dependency manually. I know that it sounds awful, but Sometimes it’s simply necessary and, as I’ll show you in a few moments, it’s not cumbersome and it will not ruin the beautiful clean design of your code
All that is needed is this simple instruction, put inside the bean that you want to initialize with Spring:
public abstract class FileManagementHelper implements Serializable {
public FileManagementHelper( Pratica pratica )
{
//inject Spring dependencies into this class and derived instances
InjectorHolder.getInjector().inject(this);
}
...
}
With that instruction, Spring will look for @SpringBean annotated fields in your class (and its derived classes) and will correctly bind them.
Well, it’s not that difficult and it will do the job, should you find yourself stuck with the accidental serialization of your application Context.
Recent Comments