首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Camel 2.9定义自定义CamelBeanPostProcessor

如何用Camel 2.9定义自定义CamelBeanPostProcessor
EN

Stack Overflow用户
提问于 2012-10-22 23:16:42
回答 1查看 3.9K关注 0票数 3

Camel使用CamelBeanPostProcessor类支持使用注释将camel端点、生产者模板等自动装配到bean中。

这门课的文件上写着:

如果您在Spring中使用该元素,那么就会隐式地安装和配置这些bean post处理器之一。因此,您不必显式地创建或配置这些实例之一。

但没有提到如何实际提供自定义实现。

我使用Spring和<camelContext...>配置骆驼的方式。如何以这种方式提供我自己的CamelBeanPostProcessor实现?原因是我想重写canPostProcessBean方法来排除几个bean类型,因为后置处理它们会给我们带来问题。他们永远不会有骆驼的特征,所以这不是一个问题。

EN

回答 1

Stack Overflow用户

发布于 2012-10-29 06:58:57

我认为解决方案是定义您自己的BeanPostProcessor。如javadoc所述

ApplicationContexts可以在其bean定义中自动检测BeanPostProcessor bean,并将它们应用于随后创建的任何bean。普通bean工厂允许对后处理器进行编程注册,适用于通过该工厂创建的所有bean。

因此,如果您像这样使用camel xml:

代码语言:javascript
复制
<camel:beanPostProcessor/>

代之以:

代码语言:javascript
复制
<bean id="camel:beanPostProcessor"
        class="org.mael.sample.camel.postprocessor.CustomCamelBeanPostProcessor" />

这样,您将不使用由xml注册的CamelBeanPostProcessor,而是使用您自己的BeanPostProcessor实现。

但是请注意,如果您想扩展CamelBeanPostProcessor类,我已经看到了来源,它使用org.apache.camel.impl.DefaultCamelBeanPostProcessor的一个实例作为委托,而扩展后者将导致一些错误,因为抛出的异常与Spring接口中声明的异常不匹配。

最好的选择是在自己的实现中也使用委托,只需覆盖所需的方法,即canPostProcessBean

编辑:

下面是我做过的一些事情,请检查TODO注释以应用您的功能,还有,巴斯丁

代码语言:javascript
复制
package org.mike.sample.camel.postprocessor;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.annotation.XmlTransient;

import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Service;
import org.apache.camel.core.xml.CamelJMXAgentDefinition;
import org.apache.camel.impl.CamelPostProcessorHelper;
import org.apache.camel.impl.DefaultCamelBeanPostProcessor;
import org.apache.camel.spring.GenericBeansException;
import org.apache.camel.util.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class CustomCamelBeanPostProcessor implements BeanPostProcessor,
        ApplicationContextAware {

    private static final transient Logger LOG = LoggerFactory
            .getLogger(CustomCamelBeanPostProcessor.class);
    @XmlTransient
    Set<String> prototypeBeans = new LinkedHashSet<String>();
    @XmlTransient
    private CamelContext camelContext;
    @XmlTransient
    private ApplicationContext applicationContext;
    @XmlTransient
    private String camelId;

    // must use a delegate, as we cannot extend DefaultCamelBeanPostProcessor,
    // as this will cause the
    // XSD schema generator to include the DefaultCamelBeanPostProcessor as a
    // type, which we do not want to
    @XmlTransient
    private final DefaultCamelBeanPostProcessor delegate = new DefaultCamelBeanPostProcessor() {
        @Override
        public CamelContext getOrLookupCamelContext() {
            if (camelContext == null) {
                if (camelId != null) {
                    LOG.trace(
                            "Looking up CamelContext by id: {} from Spring ApplicationContext: {}",
                            camelId, applicationContext);
                    camelContext = applicationContext.getBean(camelId,
                            CamelContext.class);
                } else {
                    // lookup by type and grab the single CamelContext if exists
                    LOG.trace(
                            "Looking up CamelContext by type from Spring ApplicationContext: {}",
                            applicationContext);
                    Map<String, CamelContext> contexts = applicationContext
                            .getBeansOfType(CamelContext.class);
                    if (contexts != null && contexts.size() == 1) {
                        camelContext = contexts.values().iterator().next();
                    }
                }
            }
            return camelContext;
        }

        @Override
        public boolean canPostProcessBean(Object bean, String beanName) {
            // the JMXAgent is a bit strange and causes Spring issues if we let
            // it being
            // post processed by this one. It does not need it anyway so we are
            // good to go.
            // We should also avoid to process the null object bean (in Spring
            // 2.5.x)

            // TODO - DO YOUR STUFF HERE STRELOK

            if (bean == null || bean instanceof CamelJMXAgentDefinition) {
                return false;
            }

            return super.canPostProcessBean(bean, beanName);
        }

        @Override
        public CamelPostProcessorHelper getPostProcessorHelper() {
            // lets lazily create the post processor
            if (camelPostProcessorHelper == null) {
                camelPostProcessorHelper = new CamelPostProcessorHelper() {

                    @Override
                    public CamelContext getCamelContext() {
                        // lets lazily lookup the camel context here
                        // as doing this will cause this context to be started
                        // immediately
                        // breaking the lifecycle ordering of different camel
                        // contexts
                        // so we only want to do this on demand
                        return delegate.getOrLookupCamelContext();
                    }

                    @Override
                    protected RuntimeException createProxyInstantiationRuntimeException(
                            Class<?> type, Endpoint endpoint, Exception e) {
                        return new BeanInstantiationException(type,
                                "Could not instantiate proxy of type "
                                        + type.getName() + " on endpoint "
                                        + endpoint, e);
                    }

                    protected boolean isSingleton(Object bean, String beanName) {
                        // no application context has been injected which means
                        // the bean
                        // has not been enlisted in Spring application context
                        if (applicationContext == null || beanName == null) {
                            return super.isSingleton(bean, beanName);
                        } else {
                            return applicationContext.isSingleton(beanName);
                        }
                    }

                    protected void startService(Service service, Object bean,
                            String beanName) throws Exception {
                        if (isSingleton(bean, beanName)) {
                            getCamelContext().addService(service);
                        } else {
                            // only start service and do not add it to
                            // CamelContext
                            ServiceHelper.startService(service);
                            if (prototypeBeans.add(beanName)) {
                                // do not spam the log with WARN so do this only
                                // once per bean name
                                CustomCamelBeanPostProcessor.LOG
                                        .warn("The bean with id ["
                                                + beanName
                                                + "] is prototype scoped and cannot stop the injected service when bean is destroyed: "
                                                + service
                                                + ". You may want to stop the service manually from the bean.");
                            }
                        }
                    }
                };
            }
            return camelPostProcessorHelper;
        }
    };

    public CustomCamelBeanPostProcessor() {
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        try {
            return delegate.postProcessBeforeInitialization(bean, beanName);
        } catch (Exception e) {
            // do not wrap already beans exceptions
            if (e instanceof BeansException) {
                throw (BeansException) e;
            }
            throw new GenericBeansException("Error post processing bean: "
                    + beanName, e);
        }
    }

    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        try {
            return delegate.postProcessAfterInitialization(bean, beanName);
        } catch (Exception e) {
            // do not wrap already beans exceptions
            if (e instanceof BeansException) {
                throw (BeansException) e;
            }
            throw new GenericBeansException("Error post processing bean: "
                    + beanName, e);
        }
    }

    // Properties
    // -------------------------------------------------------------------------

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

    public CamelContext getCamelContext() {
        return camelContext;
    }

    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }

    public String getCamelId() {
        return camelId;
    }

    public void setCamelId(String camelId) {
        this.camelId = camelId;
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13021332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档