我有以下组件
方案
我的库有一个类需要将自己注册为Web应用程序上下文中的bean,而不会告诉库的用户更改其代码(xml,spring context或classes)。
所以,换句话说,我有一个Class和一个spring上下文,我只希望我的类在这个spring上下文中注册而不改变其中的任何内容。 那么有没有时间spring会扫描类路径以实现某个接口的类,如果有的话接口是什么?
我尝试了什么
使用BeanFactoryPostProcessor但这要求我访问应用程序上下文并尽可能地调用addBeanFactoryPostProcessor。
使用ApplicationContextInitializer但这迫使我更改web.xml
其他一些东西,比如不同的Aware接口,但我还没有找到任何允许我的类自我注册到Bean Factory并在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"/>
如果这是不可能的我想探索一下我在班级里面可以做些什么的可能性,尽可能容易地告诉弹簧背景来拾取它。
实施例
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());
}
}
试过
但所有这些似乎都是部分工作,但它总是会得到一些时序错误,例如:ClassA需要在ClassC内部自动装配的构造函数中的输入变量,其中一些是在ClassC创建ClassA时设置的。我看到的另一个场景是ClassB无法使用Autowired ClassA,因为之前已经完成了。那么这样做的正确和好的方法是什么?
我正在运行 spring version 3.2.11.RELEASE
如果有人知道如何以一种很好的方式解决这个问题,而不是那种感觉像“丑陋的黑客”的东西,我会很高兴知道!
谢谢和最诚挚的问候!
答案 0 :(得分:2)
在这种情况下,您必须在Spring上下文xml
中包含ClassA作为spring bean<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();
}
}