使用@Autowired将依赖项注入使用“new …”创建的对象中

将bean注入helper类时遇到问题。 它基本上是这样的:我在页面构造函数中创建了一个对象,它可以完成一些工作,返回一些数据并在页面上显示这些数据。 在此辅助对象中,应通过@Autowired批注注入服务。 但是,当我使用它时,我总是得到一个空指针exception。 我也试过@SpringBean但没有帮助。 另一方面,当我使用@SpringBean将此服务直接注入到页面中时,它可以访问并且工作正常。 你知道问题出在哪里吗?

这是页面:

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

助手对象:

 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 } } 

@SpringBean仅将依赖项注入从Wicket的Componentinheritance的类中。 @Autowired只将dependency injectionSpring自己创建的类中。 这意味着您无法自动将依赖项注入使用new创建的对象中。

(编辑:您还可以通过在构造函数中注入来向您的类添加@SpringBean注入: InjectorHolder.getInjector().inject(this);

我的正常解决方法是使用我的应用程序类来提供帮助。 (我对你使用new Application(...)感到有些困惑。我认为这实际上不是org.apache.wicket.Application 。)例如:

 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 getSpringBean(Class bean) { return get().ctx.getBean(bean); } .... } 

在我的Spring应用程序上下文中

   

然后,我的帮助对象按需查找服务:

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

您可以使用@SpringBean通过调用InjectorHolder.getInjector().inject(this);将依赖关系注入非Spring-non-Wicket-new-created对象@SpringBean InjectorHolder.getInjector().inject(this); 在它的构造函数中。

例如:

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

请注意,它仅在Wicket管理的请求中调用时才有效。 如果不是(即,如果它是Quartz作业,或者在Wicket之前执行filter),则Application实例将不可用,并且注入器将不知道如何获取依赖项。

另一个解决方案是使用Spring的@Configurable 。 它使用AspectJ拦截注释对象的创建,并注入其依赖项,即使您使用new (或其他一些框架,如Hibernate,在内部创建它们)直接实例化它们。 但这需要运行时或构建时间(对我来说更好)字节码操作,这对某些人来说可能太神奇了。

最好的做法是通过工厂bean创建对象(具有Spring注入的属性,并让工厂将这些属性注入它产生的对象 – 纯IoC)。

你应该真的避免在整个地方使用SpringContext (或任何其他类似的解决方案)。 以下是部分原因列表:

  1. 你的代码与Spring方式相结合(低内聚)。
  2. 您将管道代码与业务逻辑混合在一起。
  3. 您的代码可读性较差。
  4. 它的可维护性较差(例如,更改服务bean的名称会导致代码修改 – 这违反了SRP和OCP)。
  5. 它不太可测试(例如,你需要Spring框架来测试它)。