有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有以下组件

  • 使用SpringMVC(war文件)公开的Web应用程序
  • 一个库(jar文件),它知道无论是谁使用这个库,都会使用spring

场景

我的库有一个类,它需要在web应用程序上下文中将自己注册为bean,而不告诉库的用户更改他们的代码(xml、spring上下文或类)

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

我尝试过的

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

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

  • 其他一些东西,比如不同的感知接口,但我还没有找到任何东西允许我的类自注册到Bean工厂,并在spring上下文中获取,我希望能够使用诸如计划注释之类的东西。我总是希望spring上下文中的其他人能够通过自动连线注释找到我的类

示例

我拥有并在我的库中的类

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
  • 用小扁豆来添加它。实例化
  • 通过实现ApplicationContextAware并将其强制转换为ConfigurableApplicationContext并添加BeanFactoryPostRecessor实现来添加它,我还尝试将其强制转换为ConfigurableListableBeanFactory和registerSingleton
  • 使用BeanFactoryAware和registerSingleton添加它
  • 将ClassC设置为配置,在其中添加组件Scan for spring。外部软件包工作得很好,但这样做感觉很不对

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

我正在运行spring版本3.2.11。发布

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

谢谢并致以最良好的问候


共 (1) 个答案

  1. # 1 楼答案

    在这种情况下,您必须将ClassA作为Springbean包含在spring上下文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();
        }
    }