造成问题的原因:
之前我有一个设计,需要设置一个灵活的过滤规则,但考虑到各部门之间的过滤规则过于繁复,依靠个人能力完全无法在短时间内完成,因此我写了一个接口,让使用者通过实现接口来实现他们自己的过滤规则。
问题:
设计就是让使用者通过实现该接口,并在我的配置文件里写他们的类路径,我通过反射生成这个类,并加载进我的方法。然后,问题发生了:在这个类中,无法进行Spring工厂注入。
问题发生的原理:
spring自动注入对象原理
通过创建一个BeanFactory并传入applicationContext配置文件对象,然后调用BeanFactory的getBean方法来实现相互依赖的对象获取和装配的。
如果被注入的容器没有在spring bean中配置,而是通过反射途径生成,不能获取BeanFactory,就意味着不能进行自动注入。
解决的原理
如果在组件上实现一些spring提供的接口,如BeanFactoryAware、ApplicationContextAware,就可以手动方式获取BeanFactory,实现依赖注入。
解决措施:
1:新建一个类BaseLocator:
public class BaseLocator implements BeanFactoryAware {
private static BeanFactory factory = null;
private static BaseLocator baselocator = null;
@Override
public void setBeanFactory(BeanFactory f) throws BeansException {
factory = f;
}
public BeanFactory getFactory(){
return factory;
}
public static BaseLocator getInstance() {
if (baselocator == null)
baselocator = (BaseLocator) factory.getBean("baseLocator");
return baselocator;
}
}
那么这个bean,怎么获取呢,你可以在配置类里进行bean,或者在配置文件里进行配置:
2:配置bean
@Bean
public BaseLocator getBaseLocator(){
return new BaseLocator();
}
3:再建一个类BaseAutoAware:
public class BaseAutoAware {
public BaseAutoAware() {
((AutowireCapableBeanFactory)retrieveBeanFactory())
.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
}
private BeanFactory retrieveBeanFactory() {
BaseLocator bl=new BaseLocator();
// BaseLocator bl = BaseLocator.getInstance();
return bl.getFactory();
}
}
4:在被注入的容器类中加@Data注解,并不需要加@Conpoment注解,也不要在被注入的属性值加@Autowire