使用class.forname但想要自动装配目标类的成员

时间:2015-07-06 02:35:41

标签: java spring

我有这个要求,

我的框架以某种方式从配置文件中读取类名作为字符串,我想在该类中使用方法。

明显的解决方案是使用反射, 我已经使用了反射并能够调用我想要的方法,但问题是目标类中的变量不是自动装配的。我知道我不会让spring使用反射(Spring with class.forname())自动装配字段。

有没有办法让我自动装配类变量而不是创建新实例?还是我处于僵局?

2 个答案:

答案 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");