Java Spring可以基于类(名称)向上下文添加bean并注入它吗?

Java Spring可以基于类(名称)向上下文添加bean并注入它吗?,java,spring,Java,Spring,我有一个由多个模块组成的Spring应用程序。其中一个模块要求某些Springbean出现在上下文中(它不能独立运行,因为它本身没有完整的上下文) 此模块提供了需要在许多应用程序之间共享的基本功能,这些应用程序通过使正确的bean可用(单例或请求范围,取决于需要)来定制此模块 这非常好用,我们对这个设置非常满意,因为它提供了核心功能和特定于业务的逻辑之间的分离 我现在的问题是,我有一个类,可以选择用来满足其中一个依赖项。它没有用@Component注释以防止被扫描,但是我希望项目能够选择使用这个

我有一个由多个模块组成的Spring应用程序。其中一个模块要求某些Springbean出现在上下文中(它不能独立运行,因为它本身没有完整的上下文)

此模块提供了需要在许多应用程序之间共享的基本功能,这些应用程序通过使正确的bean可用(单例或请求范围,取决于需要)来定制此模块

这非常好用,我们对这个设置非常满意,因为它提供了核心功能和特定于业务的逻辑之间的分离

我现在的问题是,我有一个类,可以选择用来满足其中一个依赖项。它没有用@Component注释以防止被扫描,但是我希望项目能够选择使用这个类或提供自己的实现

核心模块如下所示:

public interface AProvider;

@Component
public class AService {
    @Inject private AProvider aProvider;
}
并且它提供了可以选择使用的实现:

public class DatabaseBasedAProvider implements AProvider {
    @Inject private SomeOtherDependency dependency;  // <-- this needs to be injected still if used!
}
但我想要的是:

   @BeanClass  // <-- some annotation I made up
   Class<AProvider> getAProviderClass() {
       return DatabaseBasedAProvider.class;  // <-- have spring inject this!
   }

我用
@Primary
注释解决了一个与您类似的案例(如果我理解正确的话)。可能对你有好处

public interface AProvider { }
要使每个模块都有一些接口实现,请创建一个共享的默认实现

@Service
public class DefaultAProvider implements AProvider {}
然后,如果某个模块希望使用自己的实现,则使用
@Primary
来“覆盖”bean

@Primary
@Service
public class MyVerySpecialAProvider implements AProvider {}

然后,无论何时注入
AProvider
Spring
都会选择
@Primary
实现。

另一种选择是使用@Profile,另一种选择是使用@Component和@ConditionalOnProperty对AProvider类进行注释,并将不同的选择记录给用户

范例

@Component
@ConditionalOnProperty(name = "my.aprovider.choice", havingValue = "database")
public class DatabaseBasedAProvider implements AProvider {
    @Inject private SomeOtherDependency dependency;  // <-- this needs to be injected still if used!
}
@组件
@ConditionalOnProperty(name=“my.aprovider.choice”,havingValue=“database”)
公共类DatabasedProvider实现了一个Provider{

@注入private SomeOtherDependency;//我找到了一个解决方案,可以让我在客户端决定要为提供程序使用哪个类

这不是非常好,但它确实意味着我不需要对核心模块中的代码进行特定更改(因为这个模块应该是通用的)

在客户端配置中的@Configuration类中,我现在执行以下操作:

 @Component
 static class MyDatabaseBasedAProvider extends DatabaseBasedAProvider {
      // No implementation
 }
这使得Spring构造类并处理所有注入。它可以更短,并且它确实要求类是非final的,但它可以工作


如果bean丢失,客户机现在会收到警报,可以自由地进行自己的实现,如果满足他们的需要,客户机可以自由地选择一个现有的实现,而核心模块不必事先决定如何提供提供者。

我不认为类有变体,但可能会有帮助?什么会有帮助注入类而不是对象的好处是什么?我看不到值?也许我不理解问题:)@home我不想注入类。我想注入类的实例(创建它的应该是Spring,而不是我).我同意@home,如果你定义了你想让spring注入的类是b/c,你知道你想注入的实例,那么你就可以构建它吗?@artemisian让spring构建这个类,这样我就不必做类可能需要的注入(这也可能会改变)。我必须为一件事添加一个构造函数。不过我找到了一个解决方案。这是一个很好的答案,也是我考虑过要做的事情,但是我不想提供一个“默认”
AProvider
bean,因为我希望依赖的项目对此做出有意识的决定。
@Component
@ConditionalOnProperty(name = "my.aprovider.choice", havingValue = "database")
public class DatabaseBasedAProvider implements AProvider {
    @Inject private SomeOtherDependency dependency;  // <-- this needs to be injected still if used!
}
 @Component
 static class MyDatabaseBasedAProvider extends DatabaseBasedAProvider {
      // No implementation
 }