Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用@Autowired将依赖项注入到使用“Autowired”创建的对象中;新的……”;_Java_Spring_Dependency Injection_Wicket_Autowired - Fatal编程技术网

Java 使用@Autowired将依赖项注入到使用“Autowired”创建的对象中;新的……”;

Java 使用@Autowired将依赖项注入到使用“Autowired”创建的对象中;新的……”;,java,spring,dependency-injection,wicket,autowired,Java,Spring,Dependency Injection,Wicket,Autowired,我在将bean注入助手类时遇到问题。它的工作原理基本上是这样的:我在页面构造函数中创建一个对象,该对象执行一些工作,返回一些数据,并在页面上显示这些数据。在此帮助对象中,应通过@Autowired注释注入服务。然而,当我使用它时,我总是得到一个空指针异常。我也试过@SpringBean,但没用。另一方面,当我使用@SpringBean将此服务直接注入页面时,它是可访问的,并且工作正常。你知道问题出在哪里吗 这是网页: public class Page extends BasePage {

我在将bean注入助手类时遇到问题。它的工作原理基本上是这样的:我在页面构造函数中创建一个对象,该对象执行一些工作,返回一些数据,并在页面上显示这些数据。在此帮助对象中,应通过
@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
    示例。