java - 有什么方法可以知道在 Spring 中从父类使用什么 bean 吗?

标签 java spring-boot dependency-injection inversion-of-control

我遇到了这个特定问题,我无法使用 @Qualifier 因为我需要父类中的 bean。我的想法是删除 baseComponent 属性并在 BaseController 中创建一个抽象方法,例如 getComponent() 并返回 BaseComponent 所需的 bean ...但也许有一种更简洁的方法可以通过配置来做到这一点。

@RestController
public abstract class BaseController {

    @Autowired
    private BaseComponent baseComponent;

    @GetMapping("/something")
    public void doSomething() {
        baseComponent.printSomething();
    }

}

@RestController
@RequestMapping(value = "/foo")
public class FooController extends BaseController {

}

@RestController
@RequestMapping(value = "/bar")
public class BarController extends BaseController {

}

public interface BaseComponent {
    void printSomething();
}

@Component
public class FooComponent implements BaseComponent {

    @Override
    public void printSomething() {
        System.out.println("foo!");
    }

}

@Component
public class BarComponent implements BaseComponent{

    @Override
    public void printSomething() {
        System.out.println("bar!");
    }

}

最佳答案

这是我不喜欢直接 Autowiring 到私有(private)字段的原因之一。我将通过 BaseController 的构造函数注入(inject) BaseComponent 来完成此操作:

public abstract class BaseController {

   private final BaseComponent baseComponent;

   protected BaseController(BaseComponent baseComponent){
       this.baseComponent = baseComponent;
   }

   @GetMapping("/something")
   public ResponseEntity<String> getSomething(){
       return new ResponseEntity<String>(baseComponent.getSomething(), HttpStatus.OK);
   }
}

@RestController
@RequestMapping("/foo")
public class FooController extends BaseController{

   @Autowired
   public FooController(@Qualifier("fooComponent") BaseComponent baseComponent) {
      super(baseComponent);
   }
}

@RestController
@RequestMapping("/bar")
public class BarController extends BaseController{

   @Autowired
   public BarController(@Qualifier("barComponent") BaseComponent baseComponent){
       super(baseComponent);
   }
}

@Component
public class BarComponent implements BaseComponent {

   @Override
   public String getSomething() {
       return "bar";
   }
}

@Component
public class FooComponent implements BaseComponent {

   @Override
   public String getSomething() {
     return "foo";
   }
}

对/something/bar的请求将返回bar,对something/foo的请求将返回foo。

请注意,抽象BaseComponent实际上并未声明为任何类型的Spring组件,也没有自动注入(inject)任何依赖项。相反,子类是组件,依赖项被连接到它们的构造函数中,并通过 super 传递到 BaseComponent。子类构造函数为 @Qualifier 注释提供了一个位置来指定您想要的 BaseComponent

理论上,我不喜欢声明两个除了注释之外相同的类。但在实践中,我发现有时最简单的方法就是声明类来保存 Spring 注释。这比过去的 XML 配置要好。

关于java - 有什么方法可以知道在 Spring 中从父类使用什么 bean 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58526209/

相关文章:

java - spring boot 默认属性值中的大括号

java - 有没有一种方法可以仅在Java套接字中从服务器向一个客户端发送消息?

java - 在java库中使用基于环境的配置属性

java - Spring Boot 无法监听端口

带有 RoboGuice 2.0 的 Android 应用程序 - 如何使用应用程序上下文注入(inject)单例

c# - 在运行时注入(inject)依赖的最佳方式

java - SSL 连接重置

java - 在 CentOS7 上安装 Ant、JDK 和 JRE,之后仍然无法启动 .bat 文件

spring-mvc - Thymeleaf:Thymeleaf 模板解析错误

asp.net-mvc - 在运行时使用 Unity 属性注入(inject)注入(inject) IPrincipal