微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

以编程方式创建一堆 Spring Bean 作为 HashMap

如何解决以编程方式创建一堆 Spring Bean 作为 HashMap

我已经手动创建了 Spring Bean,但我无法解决以下问题。首先,我描述了我的应用程序中正在运行的部分。我有一堆注入到 HandlerConfiguration 类中的处理程序。在这个类中,我创建了一个 HashMap,其中填充了用于特定实体对象的处理程序的信息。

@Configuration
public class HandlerConfiguration {

@Autowired
private List<Handler<?>> entityHandlers;

@Bean(name = "catalog")
@Scope("prototype")
public Map<Class<?>,Handler<?>> getHandlerCatalog() {

    Map<Class<?>,Handler<?>> handlers = new HashMap<Class<?>,Handler<?>>();

    entityHandlers.stream().forEach(
            handler -> handlers.put((Class<?>) ((ParameterizedType) handler.getClass().getGenericInterfaces()[0])
                    .getActualTypeArguments()[0],handler));

    return handlers;
}

}

HashMap 稍后在 Runner 类中用于运行特定处理程序。这部分工作得很好。

@Component
public class Runner {

    @Resource(name = "catalog")
    Map<Class<?>,Handler<Entity>> entityHandlers;
    
    @Override
    public void run(Tour tour) {

        tour.getEntities().forEach(entity -> entityHandlers.get(entity.getClass()).run(entity));


    }
}

现在我创建了一个集成测试,我想手动创建配置,但我的实体 Handlers HashMap 为空。我创建了如下测试:

@RunWith(springrunner.class)
@ContextConfiguration(initializers = Test.Initializer.class)
@EnableTransactionManagement
class Test {

    static class Initializer implements ApplicationContextinitializer<ConfigurableApplicationContext> {

        public void initialize(ConfigurableApplicationContext applicationContext) {

            List<EntityHandler<?>> entityHandlersList = new ArrayList<>();
            var provider = new ClasspathScanningCandidateComponentProvider(false);
            provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
            final Set<BeanDeFinition> beanDeFinitions = provider
                    .findCandidateComponents("com.xyz.handler.dnd");

            for (BeanDeFinition className : beanDeFinitions) {
                Class<?> cls = Class.forName(className.getBeanClassName());

                entityHandler.class.isAssignableFrom(cls);

                if (EntityHandler.class.isAssignableFrom(cls)) {

                    EntityHandler<?> newInstance = (EntityHandler<?>) cls.newInstance();
                    entityHandlersList.add(newInstance);
                    ctx.getbeanfactory().registerSingleton(className.getBeanClassName(),newInstance);

                }

            }

            Map<Class<?>,Handler<?>> entityHandlers = new HashMap<Class<?>,Handler<?>>();

            entityHandlersList.stream()
                    .forEach(
                            handler -> entityHandlers.put(
                                    (Class<?>) ((ParameterizedType) handler.getClass().getGenericInterfaces()[0])
                                            .getActualTypeArguments()[0],ctx.getbeanfactory().getBean(handler.getClass())));

    
            GenericBeanDeFinition entityHandlerCatalog = new GenericBeanDeFinition();
            entityHandlerCatalog.setBeanClass(HashMap.class);
            entityHandlerCatalog.setAutowireCandidate(true);
            entityHandlerCatalog.setScope(BeanDeFinition.ScopE_PROTOTYPE);
            ctx.registerBeanDeFinition("entityHandlerCatalog",entityHandlerCatalog);

        }

    }
    
    @Test

    void test() throws Exception {
        ...
    }
}

entityHandlerCatalog 中的信息是正确的,但问题似乎出在我创建 GenericBeanDeFinition 的方式上。还是我走错了路?

提前致谢

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。