如何在Spring中将依赖项注入自我实例化的对象?

Igo*_*hin 120 java spring dependency-injection

假设我们有一个班级:

public class MyClass {
    @Autowired private AnotherBean anotherBean;
}
Run Code Online (Sandbox Code Playgroud)

然后我们创建了这个类的对象(或者其他一些框架创建了这个类的实例).

MyClass obj = new MyClass();
Run Code Online (Sandbox Code Playgroud)

是否仍然可以注入依赖项?就像是:

applicationContext.injectDependencies(obj);
Run Code Online (Sandbox Code Playgroud)

(我认为Google Guice有这样的东西)

ska*_*man 179

您可以使用autowireBean()方法执行此操作AutowireCapableBeanFactory.你将它传递给一个任意对象,Spring将它视为它自己创建的东西,并将应用各种自动装配的零碎.

为了掌握AutowireCapableBeanFactory,只需通过自动装配:

private @Autowired AutowireCapableBeanFactory beanFactory;

public void doStuff() {
   MyBean obj = new MyBean();
   beanFactory.autowireBean(obj);
   // obj will now have its dependencies autowired.
}
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是一个糟糕的模式.如果这是你真正使用MyBean的原因,为什么不将带有AnotherBean的构造函数作为参数.类似于:`code` private @Autowired AnotherBean bean; public void doStuff(){MyBean obj = new MyBean(bean); }`code`.似乎与所有这些注释一样,人们真的很困惑,并且从第1天开始就不使用java SDK中的基本模式.:( (3认同)
  • 我同意--Spring重新定义了整个语言.现在我们将接口用作具体类,将方法用作类实例,并使用各种复杂和代码繁重的方法来完成您以前使用新设计和体面设计所做的事情. (3认同)

gla*_*666 18

您还可以使用@Configurable注释标记MyClass:

@Configurable
public class MyClass {
   @Autowired private AnotherClass instance
}
Run Code Online (Sandbox Code Playgroud)

然后在创建时它将自动注入其依赖项.您还应该<context:spring-configured/>在您的应用程序上下文中使用xml.

  • Galz666,你的方法看起来更干净,我想做什么.但是我无法让它发挥作用.我没有xml文件,并且完全使用Java配置.有没有相当于`<context:spring-configured />`? (2认同)

ran*_*m86 6

刚刚得到了同样的需求,在我的情况下,它已经是非 Spring 可管理的 Java 类中的逻辑,它可以访问ApplicationContext. 灵感来自 scaffman。解决者:

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
Run Code Online (Sandbox Code Playgroud)


cod*_*eDr 6

我使用了不同的方法。我有弹簧加载的 bean,我想从创建自己线程的第三方库的扩展类中调用它们。

我使用了在这里找到的方法https://confluence.jaytaala.com/display/TKB/Super+simple+approach+to+accessing+Spring+beans+from+non-Spring+driven+classes+and+POJOs

在非托管类中:

{
    [...]
    SomeBean bc = (SomeBean) SpringContext.getBean(SomeBean.class);

    [...]
    bc.someMethod(...)
}
Run Code Online (Sandbox Code Playgroud)

然后作为主应用程序中的辅助类:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContext implements ApplicationContextAware
{
    private static ApplicationContext context;

    public static <T extends Object> T getBean(Class<T> beanClass)
    {   
        return context.getBean(beanClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException
    {   
        SpringContext.context = context;
    }
}
Run Code Online (Sandbox Code Playgroud)