java 如何指定 Spring 应该使用哪个子类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16938346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:26:09  来源:igfitidea点击:

How to specify which subclass Spring should use

javaspringinheritanceannotations

提问by Kovalsky

In my spring-based project I have a core module ('core') with a class

在我基于 spring 的项目中,我有一个带有类的核心模块('core')

@Component
public class Superclass {
    // stuff
}

instances of which are injected by type throughout the code like this:

其实例在整个代码中按类型注入,如下所示:

public class AService {

    @Autowired
    private Superclass superclass;

    // service stuff
}

I also have two other modules that depend on the core module and one of which (let's call it 'module1') extends Superclass:

我还有另外两个依赖于核心模块的模块,其中一个(我们称之为“module1”)扩展了Superclass

@component
public class Subclass extends Superclass {
    // overridden stuff
}

The other module ('module2') uses Superclassas is.

另一个模块('module2')按原样使用超类

Now I want that when I compile and run 'child1' an instance of Subclassis used everywhere an instance of Superclassis expected. So I write a configuration class:

现在我希望当我编译和运行 'child1' 时,在任何需要超类实例的地方都使用子类的实例。于是我写了一个配置类:

@Configuration
public class Module2Configuration {

    @Bean
    public Superclass superclass(){
        return new Subclass();
    }
}

When I run this I see bothSuperclassandSubclassinstantiated which is definitely notwhat I want. How do specify in 'module1' which type Spring should instantiate?

当我运行此我看到两个超类子类实例化,这绝对不是我想要的。如何在“module1”中指定 Spring 应该实例化的类型?

回答by michal

You can use @Qualifier("some name") annotation. There is more information about that: http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

您可以使用 @Qualifier("some name") 注释。有更多相关信息:http: //blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

回答by Jens Birger Hahn

Spring eagerly instantiates singleton beans as stated in the documentation:

Spring 急切地实例化单例 bean,如文档中所述:

By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process.

默认情况下,ApplicationContext 实现会在初始化过程中急切地创建和配置所有单例 bean。

which might explain why both @Componentsare created.

这可能解释了为什么两者都@Components被创建。

To specifiy which implementation is provided as a dependency you might want to check on Qualifiersthat enable to choose between different implementations. In combination with lazy loading this should do the trick.

要指定作为依赖项提供的实现,您可能需要检查能够在不同实现之间进行选择的限定符。结合延迟加载,这应该可以解决问题。

Depending on your personal taste you could also use delegation instead of inheritance using a separated interface:

根据您的个人品味,您还可以使用委托而不是使用分离接口的继承:

public interface MyService {
    public String foobar(int baz);
}

public static class CommonBehavior {
    // whatever is used by Superclass and Subclass
}

@Component @Lazy
public class FormerSuperClass implements MyService {
   private final CommonBehavior ...;
   ...
}

@Component @Lazy
public class FormerSubClass implements MyService {
   private final CommonBehavior ...;
   ...
}

Good luck!

祝你好运!

回答by wilbur_zzz

There are 2 methods: Use @Qualifier("SubclassName") Or Mark your subclass as @Component and declare the subclass when @Autowired

有两种方法:使用@Qualifier("SubclassName") 或将您的子类标记为@Component 并在@Autowired 时声明子类

In your case:

在你的情况下:

  1. Use @Qualifier("SubclassName")

    @Component
    public class Superclass {
        // stuff
    }
    
    @component
    public class Subclass extends Superclass {
        // overridden stuff
    }
    
    public class AService {
    
        @Autowired
        @Qualifier("Subclass")
        private Superclass superclass;
    
        // service stuff
    }
    
  1. 使用@Qualifier("SubclassName")

    @Component
    public class Superclass {
        // stuff
    }
    
    @component
    public class Subclass extends Superclass {
        // overridden stuff
    }
    
    public class AService {
    
        @Autowired
        @Qualifier("Subclass")
        private Superclass superclass;
    
        // service stuff
    }
    

2.Mark your subclass as @Component and declare the subclass when @Autowired

2.将你的子类标记为@Component并在@Autowired时声明子类

    public class Superclass {
        // stuff
    }

    @component
    public class Subclass extends Superclass {
        // overridden stuff
    }

    public class AService {

        @Autowired
        private Subclass subclass;

        // service stuff
    }