【问题标题】:Do classes that use DI can only be created through DI?使用 DI 的类只能通过 DI 创建吗?
【发布时间】:2015-06-26 19:39:03
【问题描述】:

我正在使用 spring 制作一个 Web 应用程序,在 web.xml 中我定义了 context-param 以查找 application-context.xml 文件,该文件扫描除控制器和仅扫描控制器的 app-servlet.xml 之外的所有内容。

application-context.xml 包含数据库的数据源,我将数据源注入到 daos 中,如下所示:

@Autowired
DataSource dataSource;

现在,如果我尝试在控制器中手动创建 DAO(我知道我可能应该为此使用服务,但它现在仅用于测试目的)我得到空指针异常,但是当我注入 DAO 时它会正确加载.

那么为什么会这样呢? DAO 不是由 DI 容器管理的,只有数据源是,那为什么我不能手动创建 dao?

【问题讨论】:

    标签: java spring spring-mvc dependency-injection


    【解决方案1】:

    Spring bean factory 和“new”是正交的:一旦您调用“new”,它就在您的手中,而不是 Spring 的。

    您描述的情况很常见:您希望 Spring 在生产中管理 bean 生命周期和依赖项,但在测试时您希望自己使用 mocks 来完成。我的建议是编写您的应用程序以使用 Spring 进行 DI 和 bean 创建,但在测试时使用构造函数手动注入模拟。

    【讨论】:

    • 我确信 spring 会以某种方式注入数据源。在测试部分,您的意思是只为测试目的创建一些构造函数吗?
    • 不,您可能更喜欢构造函数注入(我愿意)。 “不知何故”?神奇的思维。如果您只是自己创建 jdbcTemplate 实例,您的测试将运行得更快。把春天排除在外。 bean 工厂是开销。
    • 好的,在构造函数中注入弹簧并在需要时自己传递它听起来很合理。谢谢,我会接受 Daves 的回答,因为他更快,尽管如果这意味着什么,我给了你一个赞成票。
    【解决方案2】:

    是的;不受 Spring 控制的对象...嗯,不在 Spring 的控制范围内。

    有一些方法可以解决这个问题,例如,允许 newed 对象获取 Spring DI(例如,字节码操作)。

    【讨论】:

    • 所以要明确一点,如果一个类使用 DI,除了使用字节码操作之外,它只能通过 DI 创建吗?
    • @JohnSmith 是的; new 是一个 Java 结构——完全不涉及 Spring。
    猜你喜欢
    • 2022-12-15
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多