Java 使用@Autowired将依赖项注入到使用“Autowired”创建的对象中;新的……”;
我在将bean注入助手类时遇到问题。它的工作原理基本上是这样的:我在页面构造函数中创建一个对象,该对象执行一些工作,返回一些数据,并在页面上显示这些数据。在此帮助对象中,应通过Java 使用@Autowired将依赖项注入到使用“Autowired”创建的对象中;新的……”;,java,spring,dependency-injection,wicket,autowired,Java,Spring,Dependency Injection,Wicket,Autowired,我在将bean注入助手类时遇到问题。它的工作原理基本上是这样的:我在页面构造函数中创建一个对象,该对象执行一些工作,返回一些数据,并在页面上显示这些数据。在此帮助对象中,应通过@Autowired注释注入服务。然而,当我使用它时,我总是得到一个空指针异常。我也试过@SpringBean,但没用。另一方面,当我使用@SpringBean将此服务直接注入页面时,它是可访问的,并且工作正常。你知道问题出在哪里吗 这是网页: public class Page extends BasePage {
@Autowired
注释注入服务。然而,当我使用它时,我总是得到一个空指针异常。我也试过@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的组件继承的类中@Autowired
仅将依赖项注入到由Spring本身创建的类中。这意味着您无法将依赖项自动注入到使用new
创建的对象中
(编辑:您还可以通过在构造函数中注入来向类添加@SpringBean
注入:
InjectorHolder.getInjector().Injector(此);
)
我通常的解决方法是使用我的应用程序类来提供帮助。(我对您使用新应用程序(…)
感到有点困惑。我假设这实际上不是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> T getSpringBean(Class<T> bean) {
return get().ctx.getBean(bean);
}
....
}
class MyPojo {
@SpringBean
MyDumbDAO dao;
MyPojo() {
InjectorHolder.getInjector().inject(this);
}
void justDoIt() {
dao.duh(); // dao is there!
}
}
通过调用InjectorHolder.getInjector().inject(this),可以使用@SpringBean
将依赖项注入到非Spring非Wicket新创建的对象中代码>在其构造函数中
例如:
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);
}
....
}
class MyPojo {
@SpringBean
MyDumbDAO dao;
MyPojo() {
InjectorHolder.getInjector().inject(this);
}
void justDoIt() {
dao.duh(); // dao is there!
}
}
请注意,只有在Wicket托管请求中调用时,它才会工作。如果不是(即,如果它是石英作业,或者是在Wicket之前执行的过滤器),应用程序
实例将不可用,注入器将不知道如何获取依赖项
另一个解决方案是使用Spring的@可配置的
。它使用AspectJ拦截注释对象的创建,并注入其依赖项,即使您直接使用new
实例化它们(或者其他一些框架,如Hibernate,在内部创建它们)。但这需要运行时或构建时(对我来说效果更好)字节码操作,这对某些人来说可能太神奇了。最佳做法是通过工厂bean创建对象(工厂bean由Spring注入这些属性,并让工厂将这些属性注入它生成的对象-纯IoC)
您应该真正避免到处使用SpringContext(或任何其他类似的解决方案)。
以下是部分原因列表:
您的代码与Spring的耦合太多(内聚性太低)
您可以将管道代码和业务逻辑混合在一起
您的代码可读性较差
它的可维护性较差(例如,更改服务bean的名称会导致代码修改——这违反了SRP&OCP)
它的可测试性较差(例如,您需要Spring框架来测试它)
谢谢,玩了一段时间后我就是这么想的。有没有一种方法可以将依赖项(使用注释)注入到我用new…
创建的对象中?是的,你说得对,我的应用程序
对象与Wicket应用程序对象不同。依赖项注入需要某种方法来获取新创建的对象。通过从处理注入的基类继承,或者让Spring使用原型作用域创建对象,您可以通过Wicket的方式实现这一点:您还应该注意在Wicket将在会话中序列化的对象中保留对服务对象的引用。参见此答案:还添加了构造函数方法中的InjectorHolder
示例。