我正在研究Spring Boot和JMS示例,是的,我在这个
上相当新由于我们使用Oracle,我想迁移Spring Boot&从ActiveMQ到Oracle Advanced Queuing的JMS示例。但是我真的很少发现这方面的信息。
据我所知,我需要为Oracle版本替换下面的代码,但我没有设法知道如何。
@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
原始代码可在Github
找到非常感谢帮助!
答案 0 :(得分:3)
下面的配置将解决您的问题。
1 - 创建配置。对于这个答案,我已将所有配置文件压缩到应用程序文件中。你可以将它们放在单独的类中,从而分散关注点。
@SpringBootApplication
@EnableJms
public class Application {
private static Random rand = new Random();
@Bean
DataSource dataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser("yourusername");
dataSource.setPassword("yourpassword");
dataSource.setURL("jdbc:oracle:thin:@yourserver:1521:xe");
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
@Bean
public QueueConnectionFactory connectionFactory() throws Exception {
return AQjmsFactory.getQueueConnectionFactory(dataSource());
}
@Bean
public JmsTemplate jmsTemplate() throws Exception {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory());
jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
return jmsTemplate;
}
@Bean
public JmsListenerContainerFactory<?> myJMSListenerFactory(QueueConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// factory.setConcurrency("15-20");
factory.setMessageConverter(jacksonJmsMessageConverter());
configurer.configure(factory, connectionFactory);
return factory;
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
for (int i = 0; i < 10; i++) {
int waitSecs = rand.nextInt(3);
jmsTemplate.convertAndSend("YourQueueName", new Email("info@example.com", "Hello " + i, waitSecs));
}
}
}
2 - 制作JMS监听器
@Component
public class Receiver {
@JmsListener(destination = "YourQueueName", containerFactory = "myJMSListenerFactory")
public void receiveEmail(Email email) {
System.out.println("Received <" + email + ">");
}
}
3 - Maven和Oracle
您可以将oracle6或oracle7 jar分别添加到您的lib路径中,如this post所示。
Mavan文件的其余部分非常标准。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
4 - 业务对象。电子邮件等对象是您的业务领域POJO。我不会把它们放在这里。
@Testing,这就像魅力一样; - )
答案 1 :(得分:1)
我认为您不需要更改myFactory方法,而是需要创建连接到oracle队列的connectionFactory。我有类似的配置,在开发中我使用artemis来运行我的JUNIT而在prod中我使用了oracle队列。下面是我为创建connectionFactory定义的类。
paste0(tmpNames, tmpValues)
application.properties。
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.naming.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.jndi.JndiTemplate;
/**
* @author Karthik Prasad
* @since 1.0.0.0
* <p>
* Configuration file for weblogic JMS connection
*/
@Configuration
@EnableJms
@ConfigurationProperties(prefix = "spring.wls.jms")
@ConditionalOnProperty(prefix = "spring.wls.jms", name = "url")
public class WLSJmsConfiguration {
/**
* SJ4J Log instance
*/
private static final Logger LOG = LoggerFactory.getLogger(WLSJmsConfiguration.class);
/**
* provider url
*/
private String url;
/**
* username of weblogic server using which JNDI connection will be
* established
*/
private String username;
/**
* password of weblogic server using which JNDI connection will be
* established
*/
private String password;
/**
* JMS Connection factory name configured in weblogic server
*/
private String connectionFactoryName;
/**
* Name of destination queue
*/
private String targetQueue;
/**
* The Response Queue
*/
private String replyQueue;
/**
* URL to access weblogic Connectionfactory, property is set from properties
* file
*
* @see ConfigurationProperties
* @param password
* weblogic url to JNDI
*/
public void setUrl(final String url) {
this.url = url;
}
/**
* username to access weblogic queue, property is set from properties file
*
* @see ConfigurationProperties
* @param username
* weblogic username to access queue
*/
public void setUsername(final String username) {
this.username = username;
}
/**
* Password to access weblogic queue, property is set from properties file
*
* @see ConfigurationProperties
* @param password
* weblogic password to access queue
*/
public void setPassword(final String password) {
this.password = password;
}
/**
* Setter of connection factory name, property is set from properties file
*
* @see ConfigurationProperties
* @param connectionFactoryName
* ConnectionFactory from properties file
*/
public void setConnectionFactoryName(final String connectionFactoryName) {
this.connectionFactoryName = connectionFactoryName;
}
/**
* Setter for {@link #targetQueue}
*
* @param targetQueue
* the targetQueue to set
*/
public void setTargetQueue(final String targetQueue) {
this.targetQueue = targetQueue;
}
/**
* @param replyQueue
* the replyQueue to set
*/
public void setReplyQueue(final String replyQueue) {
this.replyQueue = replyQueue;
}
/**
* Get JNDI properties from properties file
*
* @return list of Weblogic jndi properties
*/
private Properties getJNDiProperties() {
final Properties jndiProps = new Properties();
LOG.debug("Initializing JndiTemplate");
LOG.debug("Url is {}", url);
jndiProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
jndiProps.setProperty(Context.PROVIDER_URL, url);
if (username != null && !username.isEmpty()) {
jndiProps.setProperty(Context.SECURITY_PRINCIPAL, username);
}
if (password != null && !password.isEmpty()) {
jndiProps.setProperty(Context.SECURITY_CREDENTIALS, password);
}
return jndiProps;
}
/**
* Create JndiTemplate for target weblogic server from provided JNDI
* properties
*
* @return Bean of Jndi Template
*/
@Bean
public JndiTemplate jndiTemplate() {
final JndiTemplate jndiTemplate = new JndiTemplate();
jndiTemplate.setEnvironment(getJNDiProperties());
return jndiTemplate;
}
/**
* Creates instance of Jndi Object Factory bean from Jndi Template
*
* @param jndiTemplate
* Jndi Template for weblogic server
* @return Bean of JndiObject Factory
*/
@Bean(name = "jmsJndiConnectionFactory")
public JndiObjectFactoryBean jndiObjectFactoryBean(final JndiTemplate jndiTemplate) {
final JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
LOG.debug("Creating Weblogic JMS connection factory");
jndiObjectFactoryBean.setJndiTemplate(jndiTemplate);
// connectionFactory name.
LOG.debug("ConnectoinFactory Name is {}", connectionFactoryName);
jndiObjectFactoryBean.setJndiName(connectionFactoryName);
return jndiObjectFactoryBean;
}
/**
* Create Jms Connection factory from Jndi Objectfactory
*
* @param jndiObjectFactoryBean
* Jndi Object factory bean
* @return Returns Jms Connection factory Bean
*/
@Bean(name = "jmsWlsConnectionFactory")
public ConnectionFactory jmsConnectionFactory(final JndiObjectFactoryBean jndiObjectFactoryBean) {
final ConnectionFactory connectionFactory = (ConnectionFactory) jndiObjectFactoryBean.getObject();
LOG.debug("ConnectoinFactory is null? {}", connectionFactory == null);
return connectionFactory;
}
/**
* Wrap Weblogic Connection Factory around caching factory
*
* @return
*/
@Bean(name = "jmsConnectionFactory")
@Primary
public ConnectionFactory connectionFactoryProxy() {
final CachingConnectionFactory jmsConnectionFactory = new CachingConnectionFactory(
(ConnectionFactory) appContext.getBean("jmsWlsConnectionFactory"));
jmsConnectionFactory.setCacheProducers(true);
jmsConnectionFactory.setSessionCacheSize(20);
return jmsConnectionFactory;
}
/**
* The instance of Target Queue retrieved from JNDI, this bean is created in
* dev profile, where one want to run the project in standalone mode but
* want to connect to Weblogic Server
*
* @return Bean of target queue instance
*/
@Bean
public Destination jmsQueueName() {
final JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
jndiObjectFactoryBean.setJndiName(targetQueue); // queue name
return (Destination) jndiObjectFactoryBean.getObject();
}
/**
* Create DestinationResolver to resolve QueueName
*
* @return Instance of JNDI Destination Resolver
*/
private DestinationResolver destinationResolver() {
final JMSDestinationResolver destinationResolver = new JMSDestinationResolver();
final JndiHelper jndiHelper = new JndiHelper(getJNDiProperties());
destinationResolver.setJndiTemplate(jndiHelper);
return destinationResolver;
}
}
您需要将spring.wls.jms.url=t3://server01:8001,server02:8003
spring.wls.jms.username=weblogic
spring.wls.jms.password=password
spring.wls.jms.connectionFactoryName=connectionFactory Name
spring.wls.jms.targetQueue=queue_name
spring.wls.jms.replyQueue=queue_name
添加到类路径中。我从wlthint3client
获得了jar并从jar创建了maven依赖并推送到我的本地repo并将jar添加为依赖。
<weblogic_home>\wlserver\server\lib