Including dependencies using @Autowired in objects created using "new ..."

I am having trouble injecting bean into helper class. It works basically like this: I create an object in the page constructor that does some work, returns some data, and I show them on the page. In this ancillary entity, the service should be entered using the @Autowired annotation. However, I always get a null pointer exception when I use it. I also tried @SpringBean , but that didn't help. On the other hand, when I embed this service directly on the page using @SpringBean , it is available and works fine. Do you know where the problem is?

This is the page:

 public class Page extends BasePage { public Page() { HelperObject object = new HelperObject(new Application("APP_NAME")); String result = object.getData(); add(new Label("label", result)); } } 

Helper Object:

 public class HelperObject { private Application app; @Autowired private Service service; public HelperObject(Application app) { this.app = app; } public String getData() { // use service, manipulate data, return a string } } 
+4
source share
3 answers

@SpringBean only injects dependencies into classes that inherit from Wicket Component . @Autowired only injects dependencies into classes created by Spring itself. This means that you cannot automatically add a dependency to an object created with new .

(Edit: you can also add an @SpringBean injection to your class by typing: InjectorHolder.getInjector().inject(this); )

My usual workaround for this is to use my application class to help. (I'm a little puzzled by your use of new Application(...) . I assume this is not really org.apache.wicket.Application .) For example:

 public class MyApplication extends AuthenticatedWebApplication implements ApplicationContextAware { private ApplicationContext ctx; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.ctx = applicationContext; } public static MyApplication get() { return (MyApplication) WebApplication.get(); } public static Object getSpringBean(String bean) { return get().ctx.getBean(bean); } public static <T> T getSpringBean(Class<T> bean) { return get().ctx.getBean(bean); } .... } 

In my Spring context:

 <!-- Set up wicket application --> <bean id="wicketApplication" class="uk.co.humboldt.Project.MyApplication"/> 

Then my helper object looks for a service on request:

 public class HelperObject { private Service getService() { return MyApplication.getSpringBean(Service.class); } 
+3
source

You can embed dependencies in Spring -non-Wicket-new-created @SpringBean using @SpringBean by calling InjectorHolder.getInjector().inject(this); in its constructor.

For instance:

 class MyPojo { @SpringBean MyDumbDAO dao; MyPojo() { InjectorHolder.getInjector().inject(this); } void justDoIt() { dao.duh(); // dao is there! } } 

Please note that it will only work if called in a request managed by Wicket. If not (i.e. if it is a Quartz job or a filter run before Wicket), the Application instance will not be available and the injector will not know how to get the dependencies.

Another solution is to use Spring @Configurable . It uses AspectJ to intercept the creation of annotated objects and embeds its dependencies, even if you create them directly using new (or some other environment like Hibernate creates them internally). But this takes time or build time (works better for me) bytecode, which may be too big for some people.

+5
source

It would be best practice to create your objects using a factory bean (with the properties that you entered using Spring) and let the factory introduce these properties to the objects it generates - pure IoC).

You really should avoid using SpringContext everywhere (or any other similar solution, for that matter). The following is an incomplete list of reasons:

  • Your code will be bound to Spring too large (with low linkage).
  • You mix plumbing code with business logic.
  • Your code is less readable.
  • Less supported (for example, changing the bean service name will result in a code change - this will violate SRP and OCP).
  • It is less testable (for example, it requires a Spring framework to test it).
+3
source

Source: https://habr.com/ru/post/1345073/


All Articles