接口的Spring依赖注入

Posted

技术标签:

【中文标题】接口的Spring依赖注入【英文标题】:Spring Dependency injection for interfaces 【发布时间】:2012-11-28 16:53:37 【问题描述】:

嗯,我一直在看一些关于 Spring 依赖注入以及 MVC 的教程,但我似乎仍然不明白我们如何具体实例化类?

我的意思是如果我有一个变量

@Autowired
ClassA someObject;

我怎样才能让 spring 创建 someObject 作为 ClassB 的实例来扩展 ClassA?比如 someObject = new ClassB();

我不太明白它在 spring 中是如何工作的,ContextLoaderListener 是自动完成的,还是我们必须创建某种配置类来准确指定 spring 应该将这些类实例化到什么? (在这种情况下,我在教程中的任何地方都没有看到)如果是,那么我们如何指定以及它的外观如何?以及我们如何配置它以在 web.xml 等中工作?

【问题讨论】:

【参考方案1】:

最佳实践

@RestController
@RequestMapping("/order")
public class OrderController 
    private final IOrderProducer _IOrderProducer;

    public OrderController(IOrderProducer iorderProducer) 
        this._IOrderProducer = iorderProducer;
    

    @GetMapping("/OrderService")
    void get() 
        _IOrderProducer.CreateOrderProducer("This is a Producer");
    

界面

@Service
public interface IOrderProducer 
    void CreateOrderProducer(String message);

实施

public class OrderProducer implements  IOrderProducer
    private KafkaTemplate<String, String> _template;

    public OrderProducer(KafkaTemplate<String, String> template) 
        this._template = template;
    

    public void CreateOrderProducer(String message)
        this._template.send("Topic1", message);
    

你需要在 spring boot 中包含 Project Lombok 依赖

摇篮implementation 'org.projectlombok:lombok'

【讨论】:

【参考方案2】:

你可以这样做:

界面:

package org.better.place

public interface SuperDuperInterface
    public void saveWorld();

实施:

package org.better.place

import org.springframework.stereotype

@Component
public class SuperDuperClass implements SuperDuperInterface
     public void saveWorld()
          System.out.println("Done");
     

客户:

package org.better.place

import org.springframework.beans.factory.annotation.Autowire;

public class SuperDuperService
       @Autowire
       private SuperDuperInterface superDuper;


       public void doIt()
           superDuper.saveWorld();
       


现在您已经定义了接口,编写了实现并将其标记为组件 - docs here。现在剩下的就是告诉 spring 在哪里可以找到组件,以便它们可以用于自动装配。

<beans ...>

     <context:component-scan base-package="org.better.place"/>

</beans>

【讨论】:

谢谢,听起来真是个很棒的答案,我想我现在明白了,我现在就试试。另一个问题,如果我们需要将参数传递给某个构造函数怎么办?它会是什么样子或者我们会使用什么? 您不能使用构造型注解来标记基于构造函数的 bean。要么使用具有自动装配依赖关系的默认构造函数,要么使用 Java / XML Bases 配置(删除 @Component 注释和 context:component-scan 元素)。有关详细信息,请参阅此帖子:javalobby.org/java/forums/t18396.html 有人还在看这个帖子吗?我的问题是 - 如果不使用 @Autowired,您将如何实现同样的目标? 酷,如果我们有多个实现呢?你会如何自动接线?因为您在服务级别自动装配,对吗?我试图直接自动装配实现,但它失败了。你可以解释吗。提前致谢! 我和@PavanSandeep 有同样的问题。有人有答案吗?【参考方案3】:

您必须在 applicationContext.xml 文件中指定要创建对象的类的类型,或者您可以使用 @Component@Service@Repository 中的任何一个直接注释该类(如果您正在使用)最新版本的春天。在 web.xml 中,如果您使用基于 xml 的配置,则必须将 xml 文件的路径指定为 servlet 的上下文参数。

【讨论】:

好吧,我假设我只需要使用 Component 注释来注释 ClassB,spring 会自动为我实例化一个新的 ClassB() 对象吗?如果 ClassA 和 ClassB 都将使用 Component 注释进行注释,那么 spring 会做什么?我理解正确吗? 如果这对您来说很常见,也可以考虑使用 xml 描述符。【参考方案4】:

是的,您必须提供指定实例的 context.xml 文件。将它交给 ApplicationContext,它会为您自动装配所有字段。

http://alvinalexander.com/blog/post/java/load-spring-application-context-file-java-swing-application

【讨论】:

以上是关于接口的Spring依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

Spring的依赖注入(DI)三种方式

spring框架——依赖注入

Spring 依赖注入的理解

Spring 依赖注入怎么回事,还有面向方面编程是怎么回事

学习笔记——Spring底层IOC实现;Spring依赖注入数值问题;Spring依赖注入方式

feign接口注入失败问题