applicationContext.getBeansOfType(type),获取不到接口实例化对象

zzx10 发布于 2019/10/31 14:04
阅读 4K+
收藏 0

【华为云1024程序员节·向云而生】预约直播 抽14件华为电子产品礼包!>>>

在测试类中使用如下代码启动spring

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean-post.xml");

spring初始化Controller类,在BeanPostProcessor中postProcessAfterInitialization中,使用applicationContext.getBeansOfType(type)无法获取该接口实例化对象数据为null

,实际该接口已经有两个实现类已经注入spring中,

其中applicationContext对象是通过实现ApplicationContextAware接口获得的。

 

但是在ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean-post.xml")加载完成,通过这个applicationContext又尝试获取applicationContext.getBeansOfType(type)对应的实例对象却成功。而且我把代码放入web项目中,ApplicationContext使用自动注入,也能正常获取到applicationContext.getBeansOfType(type)对应的实例对象。

哪位大侠,指点一下,这个为什么???

BeanPostProcessor实现代码如下:

public class RoutingBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field  f : fields) {
            if(f.isAnnotationPresent(RoutingInject.class)) {
                if(!f.getType().isInterface()) {
                    throw new BeanCreationException("RoutingInject field must be declared as an interface:" + "@Class" + clazz.getName());
                }
                try {
                    this.handleRoutingInjected(f, bean, f.getType());
                } catch (IllegalAccessException e) {
                    throw new BeanCreationException("Exception thrown when handleAutowiredRouting", e);
                }
            }
        }
        return null;
    }

    private void handleRoutingInjected(Field field, Object bean, Class type) throws IllegalAccessException {

//        HelloServiceImplV1 helloServiceImplV1 = (HelloServiceImplV1) ApplicationContextUtil.getApplicationContext().getBean("helloServiceImplV1");
//        System.out.println(helloServiceImplV1.getTest());
        Map<String, Object> candidates = applicationContext.getBeansOfType(type);
        field.setAccessible(true);
        if(candidates.size() == 1) {
            field.set(bean, candidates.entrySet().iterator().next());
        }else if(candidates.size() == 2) {
            Object proxy = RoutingBeanProxyFactory.createProxy(type, candidates);
            field.set(bean, proxy);
        }else{
            throw new IllegalAccessException("Find more bean 2 bean for type: " + type);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
加载中
0
zzx10
zzx10

谢谢大家!,是我自己弄错了RoutingBeanPostProcessor ->postProcessAfterInitialization,我默认返回了一个null导致的,改为bean即可。

0
温安适
温安适

自己实现的BeanPostProcessor需要加上@Component

@Component
RoutingBeanPostProcessor
0
zzx10
zzx10
我在配置文件中声明的:
<bean id="RoutingBeanPostProcessor" class="com.zzx.study.beanpostprocessor.RoutingBeanPostProcessor">
</bean>
0
zzx10
zzx10
Map<String, Object> candidates = applicationContext.getBeansOfType(type);

我的问题是这个方法可以获得对应接口的是实现类有两个,这个map的key没有问题显示为实现类名称,value应该也是实现类名称,问题是此时他们value都为null

0
温安适
温安适
ApplicationContextAwareProcessor 也是个BeanPostProcessor,它内部实现了ApplicationContextAware 的功能。
建议使用
InitializingBean搭配ApplicationContextAware
温安适
温安适
回复 @zzx10 : 客气了,我也是学习了
zzx10
zzx10
谢谢,是我自己弄错了RoutingBeanPostProcessor ->postProcessAfterInitialization,我默认返回了一个null导致的。
返回顶部
顶部