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

Java 如何指定Spring应该使用哪个子类,java,spring,inheritance,annotations,Java,Spring,Inheritance,Annotations,在我基于spring的项目中,我有一个带有类的核心模块“core” @Component public class Superclass { // stuff } 在整个代码中按类型注入的实例如下: public class AService { @Autowired private Superclass superclass; // service stuff } 我还有两个依赖于核心模块的其他模块,其中一个我们称之为“module1”扩展超类: 另一个

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

@Component
public class Superclass {
    // stuff
}
在整个代码中按类型注入的实例如下:

public class AService {

    @Autowired
    private Superclass superclass;

    // service stuff
}
我还有两个依赖于核心模块的其他模块,其中一个我们称之为“module1”扩展超类:

另一个模块“module2”按原样使用超类

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

@Configuration
public class Module2Configuration {

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

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

您可以使用@Qualifiersome名称注释。
还有更多信息:

您可以使用@Qualifiersome名称注释。
还有更多信息:

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

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

这可能解释了为什么创建这两个@组件

要指定作为依赖项提供的实现,您可能需要检查该实现,以便在不同的实现之间进行选择。与延迟加载相结合,这应该可以做到这一点

根据您的个人喜好,您也可以使用委派而不是使用单独的接口继承:

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 ...;
   ...
}

祝你好运

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

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

这可能解释了为什么创建这两个@组件

要指定作为依赖项提供的实现,您可能需要检查该实现,以便在不同的实现之间进行选择。与延迟加载相结合,这应该可以做到这一点

根据您的个人喜好,您也可以使用委派而不是使用单独的接口继承:

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 ...;
   ...
}

祝你好运

有两种方法:使用@qualifier子类名称或将子类标记为@Component,并在@Autowired时声明子类

    public class Superclass {
        // stuff
    }

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

    public class AService {

        @Autowired
        private Subclass subclass;

        // service stuff
    }
就你而言:

使用@qualifier子类名称

@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.将子类标记为@Component,并在@Autowired时声明子类

    public class Superclass {
        // stuff
    }

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

    public class AService {

        @Autowired
        private Subclass subclass;

        // service stuff
    }

有两种方法:使用@QualifierSubclassName或将子类标记为@Component,并在@Autowired时声明子类

    public class Superclass {
        // stuff
    }

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

    public class AService {

        @Autowired
        private Subclass subclass;

        // service stuff
    }
就你而言:

使用@qualifier子类名称

@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.将子类标记为@Component,并在@Autowired时声明子类

    public class Superclass {
        // stuff
    }

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

    public class AService {

        @Autowired
        private Subclass subclass;

        // service stuff
    }

谢谢,我想到了这一点,但是“核心”模块对“模块1”的子类一无所知,我想在任何地方都使用它,“核心”的代码需要超类。我不知道,我应该如何限定服务的字段,以便它比没有限定符知道更多。或者我应该以某种方式限定子类吗?或者两者都有?你能详细解释一下吗?嘿,我不确定我是否正确理解了你的应用程序结构和意图,所以请原谅:-。两种实现是否必须在同一应用程序/应用程序上下文中处于活动状态?也许您可以删除@Component注释,因为使用@Bean您正在创建一个新实例?我通常的策略是从超类中创建一个单独的接口,将其放入“核心”,并分别在模块1和模块2中创建所需的实现。我希望我能更接近您的需求……我想我会按照您的建议,在核心中使用单独的接口,在模块中使用单独的实现。但最初的想法是,“核心”模块将是一个具有自己的spring配置的成熟应用程序,不知道其他模块,“模块1”将扩展核心的一个Bean超类,在子类中稍微改变其行为,然后告诉spring使用它,而不是创建一个稍有不同的应用程序版本。我想我没能从这个问题上说清楚。我的错。我想给你更多的提示,但如果没有更多的上下文,很难判断其他选项是否更合适。如果您可以再花一个小时来看看Spring文档。它有很多小例子。谢谢,我想到了这一点,但是“核心”模块对“模块1”的子类一无所知,我想在任何地方都使用它“核心”的代码需要超类。我不知道,我应该如何限定服务的字段,以便它比没有限定符知道更多。或者我应该以某种方式限定子类吗?或者两者都有?你能详细解释一下吗?嘿,我不确定我是否正确理解了你的应用程序结构和意图,所以请原谅:-。两种实现是否必须在同一应用程序/应用程序上下文中处于活动状态?也许您可以删除@Component注释,因为使用@Bean您正在创建一个新实例?我通常的策略是创建一个单独的接口f
rom超类,将其放入“核心”,并分别在模块1和模块2中创建所需的实现。我希望我能更接近您的需求……我想我会按照您的建议,在核心中使用单独的接口,在模块中使用单独的实现。但最初的想法是,“核心”模块将是一个具有自己的spring配置的成熟应用程序,不知道其他模块,“模块1”将扩展核心的一个Bean超类,在子类中稍微改变其行为,然后告诉spring使用它,而不是创建一个稍有不同的应用程序版本。我想我没能从这个问题上说清楚。我的错。我想给你更多的提示,但如果没有更多的上下文,很难判断其他选项是否更合适。如果您可以再花一个小时来看看Spring文档。它有很多小例子。