我有这个要求,
我的框架以某种方式从配置文件中读取类名作为字符串,我想在该类中使用方法。
明显的解决方案是使用反射, 我已经使用了反射并能够调用我想要的方法,但问题是目标类中的变量不是自动装配的。我知道我不会让spring使用反射(Spring with class.forname())自动装配字段。
有没有办法让我自动装配类变量而不是创建新实例?还是我处于僵局?
答案 0 :(得分:5)
选项1 :如果您有权访问当前的Spring ApplicationContext
,则可以执行以下操作:
String className = <load class name from configuration>
Class<?> clazz = Class.forName(className);
ApplicationContext applicationContext = <obtain Spring ApplicationContext>
applicationContext.getBean(clazz);
这当然意味着您希望加载其实例的类是Spring托管bean。这是一个具体的例子:
package org.example.beans;
@Component
class Foo { ... }
@Component
class SpringApplicationContext implements ApplicationContextAware {
private static ApplicationContext CONTEXT;
@Override
public void setApplicationContext(final ApplicationContext context) throws BeansException
CONTEXT = context;
}
public static <T> T getBean(String className) {
return CONTEXT.getBean(Class.forName(className));
}
}
选项2 :您可以手动创建所需类的实例,然后让Spring填充其依赖项。
这又需要访问ApplicationContext
。例如:
T object = Class.forName(className).newInstance();
applicationContext..getAutowireCapableBeanFactory().autowireBean(object);
答案 1 :(得分:1)
这是可能的。看看Spring的JUnit测试集成是如何实现的。那是在弹簧测试模块中。
跑步者是SpringJUnit4ClassRunner
,但实际的注射代码在DependencyInjectionTestExecutionListener.injectDependencies
。它使用实现AutowriteCapableBeanFactory
的Spring上下文。
执行此操作的代码如下所示。请注意,这假设您已使用注释来指示需要自动装配哪些字段。
Object bean = ...;
AutowireCapableBeanFactory beanFactory = ...;
beanFactory.autowireBeanProperties(bean, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
beanFactory.initializeBean(bean, "beanName");