【问题标题】:POJO Injection in Spring similar to CDISpring中的POJO注入类似于CDI
【发布时间】:2017-05-16 08:41:35
【问题描述】:

我有一些来自外部库的 java 对象,我需要在我的 spring 项目中注入这些对象。问题是库中的类不知道任何spring api的

如果我使用 @Autowired 将 bean 从库中注入到服务中,我会得到 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type

以下是我的服务类

@Path("/test")
public class TestService {

    @Autowired
    SomeOtherClass service;

    @GET
    public Response get(){
        return Response.ok(service.someMethod()).build();
    }
}

以下是我不知道春天的图书馆课程

public class SomeOtherClass {

    public String someMethod(){
        return "Data from library";
    }
}

当我调用我的服务时,我得到异常

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.SomeOtherClass' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

有没有办法在spring中注入一个类似于**CDI**中的注入的普通Java对象? 有一个选项可以定义 applicationcontext.xml 并在 xml 中定义 SomeOtherClass 并使用 getBean,但我不想这样做。还有其他选择吗?

注意:

无法考虑以下选项,因为我有100's 的类来自库

  1. Cannot use applicationcontext.xml

  2. Cannot @Configuration @Bean to produce beans.

【问题讨论】:

  • 你不需要getBean 你只需要声明一个SomeOtherClass 的实例然后@Autowired 就可以工作了。 Spring 只会注入托管 bean(就像 CDI 一样,如果某些东西不是托管 bean,它也不会注入任何东西)。
  • 那么不要使用 spring... 你需要让这些类成为 spring 托管实例,否则它将无法工作。如果您不能(或不会)使用基于 xml 或 java 的配置,那么 spring 无能为力。 (虽然你可以扩展 spring 来检测/扫描这些类,但这需要一些关于 spring 的内部和工作的知识)。

标签: spring dependency-injection


【解决方案1】:

你可以像下面这样使用@Configuration 和@Bean 注解 -

创建一个新类:

@Configuration
public class AppConfig {

    @Bean
    SomeOtherClass someOtherClassBean(){ return new SomeOtherClass();}

}

现在自动接线应该可以工作了。 它所做的实际上是创建一个 bean 并让 Spring 知道它。

【讨论】:

  • 我想到了这个选项,但我有很多来自图书馆的课程(100 个)。有没有办法避免编写 Configuration 和 Bean 并告诉 spring 在 Autowire 中注入普通对象?
  • @M.Deinum 为什么它不会编译?
  • 指定返回类型的空方法根本无法编译。它什么也不返回...(至少在编辑之前)。
【解决方案2】:

也许尝试以编程方式将 bean 添加到 IoC 容器中: Add Bean Programmatically to Spring Web App Context

您需要找到所有要实例化的类并使用链接问题中的一种方法。

【讨论】:

  • 编写额外的代码来实现注入类似于拥有上下文文件或bean配置。我正在寻找一些开箱即用的支持,类似于 java ee 中的 bean-discovery-mode="ALL"
  • 我不确定是否有类似的东西,甚至(对我而言)没有这样的东西是有道理的。在我看来,在大多数用例中,控制进入 IoC 容器的内容是有意义的。希望你能找到有用的东西。让我们知道:-)
【解决方案3】:

您可以使用反射以编程方式添加 Bean 定义。

    @Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    Reflections ref = new Reflections(new ConfigurationBuilder()
            .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
            .setUrls(ClasspathHelper.forPackage(PACKAGE_NAME))
            .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(PACKAGE_NAME))));
    ref.getSubTypesOf(Object.class).stream()
            .forEach(clazz -> {
                logger.info("Defining pojo bean: {} -> {}", Introspector.decapitalize(clazz.getSimpleName()), clazz.getCanonicalName());
                registry.registerBeanDefinition(Introspector.decapitalize(clazz.getSimpleName()),
                        BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition());
            });
}

随后,这些 bean 可以在其他地方为 @Autowired。见要点:https://gist.github.com/ftahmed/a7dcdbadb8bb7dba31ade463746afd04

【讨论】:

    猜你喜欢
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    相关资源
    最近更新 更多