如何在 Apache Camel 路由初始化中捕获 BeanCreationException 以允许我的 Spring 应用程序启动?
How do I catch BeanCreationException in Apache Camel route initialization to allow my Spring application to start anyway?
我正在使用 Apache Camel,我定义了一条路由,用于接收来自位于 2 个不同服务器上的 2 个队列的输入。理想情况下,我希望从两个服务器都使用,但我也希望能够 运行 当两个目的地之一出现故障时应用程序。
这是我的路线:
try {
from("mccdsJmsRequest1:queue:{{mccds.queues.in}}").to("direct:apolloMccdsRoute");
} catch (Exception e){
// debug line
System.out.println("Ms1 not reachable");
e.printStackTrace();
}
try {
from("mccdsJmsRequest2:queue:{{mccds.queues.in}}").to("direct:apolloMccdsRoute");
} catch (Exception e){
// debug line
System.out.println("Ms2 not reachable");
e.printStackTrace();
}
from("direct:apolloMccdsRoute").routeId("apolloMCCDSRoute")
// Main route starts here...
我在这里声明我的豆子:
@Bean
public JndiObjectFactoryBean mccdsJmsConnectionFactory1() {
JndiObjectFactoryBean cf = new JndiObjectFactoryBean();
cf.setJndiEnvironment(prodMccdsJndiProperties.getJndi1());
cf.setJndiName(jndiName1);
return cf;
}
@Bean
public JndiObjectFactoryBean mccdsJmsConnectionFactory2(){
JndiObjectFactoryBean cf = new JndiObjectFactoryBean();
cf.setJndiEnvironment(prodMccdsJndiProperties.getJndi2());
cf.setJndiName(jndiName2);
return cf;
}
@Inject
private CamelContext camelContext;
@Bean
public JmsComponent mccdsJmsRequest1() {
JmsComponent ac = new JmsComponent(camelContext);
ac.setConnectionFactory((ConnectionFactory) mccdsJmsConnectionFactory1().getObject());
ac.setConcurrentConsumers(5);
return ac;
}
@Bean
public JmsComponent mccdsJmsRequest2(){
JmsComponent ac = new JmsComponent(camelContext);
ac.setConnectionFactory((ConnectionFactory) mccdsJmsConnectionFactory2().getObject());
ac.setConcurrentConsumers(5);
return ac;
}
如果其中一个连接工厂不可访问,则应用程序不会启动。
我想捕捉一个忽略异常:
o.s.b.f.s.DefaultListableBeanFactory : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mccdsJmsConnectionFactory2' defined in class path resource [ca/bell/it/spa/uim/apollo/maximo/config/mccds/ProdMccdsJmsConfiguration.class]: Invocation of init method failed; nested exception is javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://someTestServerIP: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused (Connection refused); No available router to destination]
那是行不通的,因为你的 try/catch 块在你的路线执行期间从未执行过。在您的代码中,您只会在 Camel 在构建路由时在应用程序启动时初始执行此代码时遇到异常,而它并不关心您的队列是否存在。
相反,您需要确定在构建之后执行路线时何时发生错误。有很多方法可以做到这一点,但一个好的开始可能是看看 Camel 的 Exception Clause
另一种甚至更好的选择是使用 Camel 的 Load Balancer 。它允许您尝试任意数量的端点,并在一个端点因异常而失败时故障转移到下一个端点。
尝试将 lookupOnStartup
设置为 false。 (将 cf.setLookupOnStartup(false)
添加到 mccdsJmsConnectionFactory1
和 mccdsJmsConnectionFactory2
bean 定义中。)
同时检查这个线程:http://forum.spring.io/forum/spring-projects/batch/95620-jndi-lookup
我正在使用 Apache Camel,我定义了一条路由,用于接收来自位于 2 个不同服务器上的 2 个队列的输入。理想情况下,我希望从两个服务器都使用,但我也希望能够 运行 当两个目的地之一出现故障时应用程序。
这是我的路线:
try {
from("mccdsJmsRequest1:queue:{{mccds.queues.in}}").to("direct:apolloMccdsRoute");
} catch (Exception e){
// debug line
System.out.println("Ms1 not reachable");
e.printStackTrace();
}
try {
from("mccdsJmsRequest2:queue:{{mccds.queues.in}}").to("direct:apolloMccdsRoute");
} catch (Exception e){
// debug line
System.out.println("Ms2 not reachable");
e.printStackTrace();
}
from("direct:apolloMccdsRoute").routeId("apolloMCCDSRoute")
// Main route starts here...
我在这里声明我的豆子:
@Bean
public JndiObjectFactoryBean mccdsJmsConnectionFactory1() {
JndiObjectFactoryBean cf = new JndiObjectFactoryBean();
cf.setJndiEnvironment(prodMccdsJndiProperties.getJndi1());
cf.setJndiName(jndiName1);
return cf;
}
@Bean
public JndiObjectFactoryBean mccdsJmsConnectionFactory2(){
JndiObjectFactoryBean cf = new JndiObjectFactoryBean();
cf.setJndiEnvironment(prodMccdsJndiProperties.getJndi2());
cf.setJndiName(jndiName2);
return cf;
}
@Inject
private CamelContext camelContext;
@Bean
public JmsComponent mccdsJmsRequest1() {
JmsComponent ac = new JmsComponent(camelContext);
ac.setConnectionFactory((ConnectionFactory) mccdsJmsConnectionFactory1().getObject());
ac.setConcurrentConsumers(5);
return ac;
}
@Bean
public JmsComponent mccdsJmsRequest2(){
JmsComponent ac = new JmsComponent(camelContext);
ac.setConnectionFactory((ConnectionFactory) mccdsJmsConnectionFactory2().getObject());
ac.setConcurrentConsumers(5);
return ac;
}
如果其中一个连接工厂不可访问,则应用程序不会启动。 我想捕捉一个忽略异常:
o.s.b.f.s.DefaultListableBeanFactory : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mccdsJmsConnectionFactory2' defined in class path resource [ca/bell/it/spa/uim/apollo/maximo/config/mccds/ProdMccdsJmsConfiguration.class]: Invocation of init method failed; nested exception is javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://someTestServerIP: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused (Connection refused); No available router to destination]
那是行不通的,因为你的 try/catch 块在你的路线执行期间从未执行过。在您的代码中,您只会在 Camel 在构建路由时在应用程序启动时初始执行此代码时遇到异常,而它并不关心您的队列是否存在。
相反,您需要确定在构建之后执行路线时何时发生错误。有很多方法可以做到这一点,但一个好的开始可能是看看 Camel 的 Exception Clause
另一种甚至更好的选择是使用 Camel 的 Load Balancer 。它允许您尝试任意数量的端点,并在一个端点因异常而失败时故障转移到下一个端点。
尝试将 lookupOnStartup
设置为 false。 (将 cf.setLookupOnStartup(false)
添加到 mccdsJmsConnectionFactory1
和 mccdsJmsConnectionFactory2
bean 定义中。)
同时检查这个线程:http://forum.spring.io/forum/spring-projects/batch/95620-jndi-lookup