【问题标题】:Support for autowiring in a class not instantiated by spring (3)支持在未由 spring 实例化的类中自动装配 (3)
【发布时间】:2012-10-26 10:22:51
【问题描述】:

我意识到这应该是非常基本的,但在 Helloworld 之后我还没有找到第二步示例

所以我拥有的是:

spring config xml 称为 spring-beans.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:annotation-config />
    <context:component-scan base-package="org" />

</beans>

一个spring上下文初始化类:

public static void main(String[] args) {
    // initialize Spring
    ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring-beans.xml");

    App app = (App) context.getBean("app");
    app.run();
}

AppImpl类的相关细节:

@Component("app")
public final class AppImpl implements App{    

    // focus of question: This autowiring works
    @Autowired
    private DAO1 dao1;


    public void run() {
        //focus of question: This works as daoclass is instantiated properly                   
        obj1s = dao1.myFind();            

        badJobs = runJobs(obj1s);
    }

    private List<Obj1> runJobs(final List<Obj1> obj1s) {        
        List<Obj1> jobsGoneBad = new ArrayList<Obj1>();
        for (Obj1 next : obj1s) {

            // focus of question: usage of new keyword, thus not spring container managed?
            Job job = new JobImpl(next);
            job.run();

        }
        return jobsGoneBad;
    }    
}

JobImpl的相关细节:

public class JobImpl implements Job {

    private Obj1 obj1;

    // focus of question: can't autowire
    @Autowired
    private DAO2 dao2;

    @Override
    public void run() {
        //focus of question: opDAO == null - not initialized by @Autowired
        Obj2 obj2 = dao2.myFind();        
    }

}

DAO1的相关细节:

@Repository("DAO1") //Focus of question: DAO1 is a repository stereotype
public class DAO1 {

    myfind() { ...}
}

DAO2的相关细节:

@Repository("DAO2") //Focus of question: DAO2 is a repository stereotype
public class DAO2 {        

    myfind() { ...}
}

对,所以我通过 springcontext 调用初始化 App,然后通过使用 @Autowired 成功实例化 DAO1 实例。

然后我创建了一个 Job 的非托管实例,并希望通过使用 @Autowired 在该类中注入“singeltonish”依赖项

这两个 Dao 类都是 spring 刻板印象,扫描仪发现它们很好。

所以我的问题基本上是,我应该如何实例化作业实例以便我可以在其中使用@Autowired 概念?

如果我需要一个全局可访问的应用程序上下文,我该如何最好地引入它?

【问题讨论】:

    标签: java spring autowired


    【解决方案1】:

    您只能在 Spring 托管 bean 中使用 Spring Bean 功能,例如注入!

    但是你可以使用@Configurable注解,但这需要你使用REAL AspectJ。 如果一个类由 @Configurable 注释(并且您使用 AspectJ),那么即使此类是由普通的 new 创建的,您也可以使用 Springs Injection Annotations。

    @见

    【讨论】:

    • 此信息与解决当前设计的问题相关,但我认为通过重新设计可以更好地解决问题,如另一篇文章中所建议的那样。仍然显然值得一票!
    【解决方案2】:

    Spring bean 默认是单例的。但是,您需要的是多个实例,最重要的是,多个实例创建了运行时。

    一种可能性是为此使用method injection。您将创建一个容器感知作业工厂,该工厂将从容器中请求新实例。

    (我认为你需要在那些运行时实例中注入 DAO 引用有点可疑......我可能会尝试重新考虑逻辑。为什么你不能只在构造函数参数中提供 DAO 引用,例如,或者从其他地方完全使用它。你可以在 dao 中有一个方法来接受 Jobs 实例,或者 JobImpl 中的 runWith(DAO2 dao) 东西,它可以满足在其他地方注入的类,或者 JobProcessor将注入 daos 并从 Jobs 实例询问相关信息的服务...)

    【讨论】:

    • 感谢您的礼貌。 :) 你介意详细说明“其他地方”的想法吗?
    【解决方案3】:

    @Autowired 不起作用,因为您的 JobImpl 对象不是由 spring 管理的,因此它永远没有机会注入它。 Spring 托管 bean 是在组件扫描期间或在 XML 定义中创建实例的那些。 JobImpl 在您的情况下被实例化为普通的 Java 对象。

    一种解决方案是在 spring 上下文中用手动查找替换自动连接。

    private DAO2 dao2 = SpringApplicationContext.getApplicationContext ().getBean (DAO2.class);
    

    @Autowired 在@AppImpl 中工作,因为它被注释为@Component。这会在其类路径扫描期间将其标记为 spring,它将创建此类的实例并执行任何自动装配/注入。

    【讨论】:

    • 感谢您的意见。我知道为什么它不起作用。我更多的是在寻找最佳替代实施的意见,以使其发挥作用。我不认为每次我需要解决它时都运行到应用程序上下文,就像建议重新设计另一个答案一样好
    【解决方案4】:

    @Component 注释添加到您的JobImpl 类。在 xml 中为此类添加组件扫描,您的自动装配将适用于 dao2(提供 getter-setter 方法)。

    【讨论】:

    • 我认为这不是问题——问题是他在运行时手动创建 JobImpl 类,绕过了 spring 容器。
    • 我明白了,但是您可能已经注意到 JobImpl 接收一个 Obj1 构造函数参数,并且旨在处理数千个参数,这使使用 @Component 的选项无效,因为它不是带有单例的对象行为。
    猜你喜欢
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多