java - 如何从 spring 上下文外部将 spring bean 注册到 spring 上下文中?

标签 java spring applicationcontext spring-bean

我有以下组件

  • 使用 Spring MVC(war 文件)公开的 Web 应用程序。
  • 一个库(jar 文件),它知道无论谁使用该库,都使用 spring。

场景

我的库有一个类,需要将自身注册为 Web 应用程序上下文中的 bean,而不告诉库的用户更改其代码(xml、spring 上下文或类)。

所以,换句话说,我有一个类和一个 spring 上下文,我只想从我的类中注册这个 spring 上下文,而不更改其中的任何内容。 那么spring是否会在类路径中扫描实现某个接口(interface)的类,如果有的话是什么接口(interface)?

我尝试过的

  • 使用 BeanFactoryPostProcessor,但这需要我访问应用程序上下文并尽可能调用 addBeanFactoryPostProcessor。

  • 使用 ApplicationContextInitializer 但这迫使我更改 web.xml

  • 还有很多其他的东西,比如不同的 Aware 接口(interface),但我还没有找到任何东西可以让我的类 self 注册到 Bean Factory 并在 spring 上下文中被拾取,我希望能够使用诸如计划注释之类的东西。我总是希望 spring 上下文中的其他人能够通过 Autowired 注释找到我的类。

示例

我拥有并在我的库中的类

package spring.outside

public class ClassA {
    @Scheduled(fixedDelay=5000)
    public void doSomething() {
    }
}

我的库的用户拥有的类

package spring.inside

public class ClassB {
    @Autowired 
    private ClassA classA;
}

有一个包含类似内容的 spring 文件,但我不拥有

    <context:component-scan base-package="spring.inside"/>
<小时/> <小时/>

如果这是不可能的我想探索我在 Spring 的类里面可以做的事情的可能性,以尽可能轻松地告诉 Spring 上下文来拾取它。

示例

package spring.outside

public class ClassA {
    @Scheduled(fixedDelay=5000)
    public void doSomething() {
    }
}

我的库的用户拥有的类

package spring.inside

public class ClassB {
    @Autowired 
    private ClassA classA;
}

另一个类,用于启动 ClassA 并将其放入 spring 应用程序上下文中,我只是显示我现在在其中测试的一些不同事物的代码,因为我不知道它应该是什么样子.

package spring.inside

public class ClassC implements BeanFactoryPostProcessor, ApplicationContextInitializer, BeanFactoryAware, ApplicationContextAware {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerSingleton("classA", new ClassA());
    }

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        applicationContext.addBeanFactoryPostProcessor(this);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        ((ConfigurableListableBeanFactory)beanFactory).registerSingleton("classA", new ClassA());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ((ConfigurableApplicationContext)applicationContext.getParentBeanFactory()).addBeanFactoryPostProcessor(this);
        ((ConfigurableListableBeanFactory)applicationContext.getParentBeanFactory()).registerSingleton("classA", new ClassA());
    }
}

尝试过

  • 使用 BeanFactoryPostProcessor 和 registerSingleton 添加它
  • 使用 ApplicationContextInitializer 添加它,然后结合使用 addBeanFactoryPostProcessor 和 BeanFactoryPostProcessor
  • 通过BeanUtils.instantiate添加
  • 通过实现 ApplicationContextAware 并将其转换为 ConfigurableApplicationContext 并添加 BeanFactoryPostPrecessor 实现来添加它,我还尝试了类型转换为 ConfigurableListableBeanFactory 和 registerSingleton。
  • 使用 BeanFactoryAware 和 registerSingleton 来添加它。
  • 将我的 ClassC 设置为一个配置,其中我为 spring.outside 包添加了 componentScan,效果非常好,但这样做感觉非常错误。

但是所有这些似乎都部分起作用,但最终总是会出现一些计时错误,例如:ClassA 需要在 ClassC 内部 Autowiring 的构造函数中输入变量,其中一些变量是在 ClassC 创建 ClassA 时设置的。我看到的另一个场景是 ClassB 无法自动连接 ClassA,因为之前已经完成了。那么正确且好的方法是什么?

我正在运行spring版本3.2.11.RELEASE

如果有人知道如何以一种好的方式解决这个问题,而不是感觉像“丑陋的黑客”的东西,我会很高兴知道!

谢谢并致以最诚挚的问候!

最佳答案

在这种情况下,您必须将 ClassA 作为 spring bean 包含在 Spring Context XML

<bean id="classA" class="spring.inside.ClassA">

或使用配置类

package spring.inside;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import spring.outside.ClassA;

@Configuration
public class AppConfiguration {    

    @Bean
    ClassA classA() {
        return new ClassA();
    }
}

关于java - 如何从 spring 上下文外部将 spring bean 注册到 spring 上下文中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31740331/

相关文章:

java - 定期增量读取文本文件作为字节数组忽略部分附加行

java - 从字符串中拆分地理坐标的正则表达式

java - 如何在我的 Nexus 5 设备上使用其他语音识别服务?

spring - 如何在上下文卸载时关闭连接池?

java - 带有 Hibernate 和 Spring 的通用 DAO,是不是比这更好的方法?

java - 如何从 JdbcTemplate 获取 csv 列表?

java - 配置类中的 getBeansOfType

java - 什么是NoSuchBeanDefinitionException,我该如何解决?

java - 在 RHS 处引用 Spring XML 中的属性的属性?

java - 哪种方法可以快速编译 Ginger Bread 源代码?