手工添加bean到spring容器


@Configuration
@ConditionalOnClass(DefaultMQPushConsumer.class)
@EnableConfigurationProperties(RocketMQProperties.class)
@ConditionalOnProperty(prefix = "spring.rocketmq", value = "nameServer")
@Order
public static class ListenerContainerConfiguration implements ApplicationContextAware, InitializingBean {
    private ConfigurableApplicationContext applicationContext;

    private AtomicLong counter = new AtomicLong(0);

    @Resource
    private StandardEnvironment environment;

    @Resource
    private RocketMQProperties rocketMQProperties;

    private ObjectMapper objectMapper;

    public ListenerContainerConfiguration() {
    }

    @Autowired(required = false)
    public ListenerContainerConfiguration(
        @Qualifier("rocketMQMessageObjectMapper") ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    }

    @Override
    public void afterPropertiesSet() {
        Map<String, Object> beans = this.applicationContext.getBeansWithAnnotation(RocketMQMessageListener.class);

        if (Objects.nonNull(beans)) {
            beans.forEach(this::registerContainer);
        }
    }

    private void registerContainer(String beanName, Object bean) {
        Class clazz = AopUtils.getTargetClass(bean);

        if (!RocketMQListener.class.isAssignableFrom(bean.getClass())) {
            throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());
        }

        RocketMQListener rocketMQListener = (RocketMQListener) bean;
        RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
        BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultRocketMQListenerContainer.class);
        beanBuilder.addPropertyValue(PROP_NAMESERVER, rocketMQProperties.getNameServer());
        beanBuilder.addPropertyValue(PROP_TOPIC, environment.resolvePlaceholders(annotation.topic()));

        beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, environment.resolvePlaceholders(annotation.consumerGroup()));
        beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode());
        beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax());
        beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel());
        beanBuilder.addPropertyValue(PROP_SELECTOR_EXPRESS, environment.resolvePlaceholders(annotation.selectorExpress()));
        beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType());
        beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener);
        if (Objects.nonNull(objectMapper)) {
            beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper);
        }
        beanBuilder.setDestroyMethodName(METHOD_DESTROY);

        String containerBeanName = String.format("%s_%s", DefaultRocketMQListenerContainer.class.getName(), counter.incrementAndGet());
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition());

        DefaultRocketMQListenerContainer container = beanFactory.getBean(containerBeanName, DefaultRocketMQListenerContainer.class);

        if (!container.isStarted()) {
            try {
                container.start();
            } catch (Exception e) {
                log.error("started container failed. {}", container, e);
                throw new RuntimeException(e);
            }
        }

        log.info("register rocketMQ listener to container, listenerBeanName:{}, containerBeanName:{}", beanName, containerBeanName);
    }
}

你可能感兴趣的:(java)