Как перенести Spring Boot JMS из ActiveMQ в Oracle Advanced Queueing
Я изучаю пример Spring Boot и JMS, и да, я довольно новичок в этом
поскольку мы работаем с Oracle, я хотел бы перенести пример Spring Boot & JMS из ActiveMQ в Oracle Advanced Queueing. Однако я действительно нахожу очень мало информации об этом.
насколько я вижу, мне нужно заменить код ниже для версии 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
помощь была бы очень признательна!
2 ответов
конфигурация ниже решит ваши вопросы.
1-Создайте конфигурацию. Для этого ответа я поместил все файлы конфигурации compact в файл приложения. Вы можете поместить их в отдельные классы, тем самым разделяя проблемы.
@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 отдельно к пути lib, как показано в этот пост.
остальная часть файла 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. Я не положу их сюда.
@тестирования, это работает как шарм ;-)
Я не думаю, что вам нужно изменить метод myFactory как таковой, вместо этого вам нужно создать connectionFactory, который подключается к очереди oracle. У меня была аналогичная конфигурация, в dev я использовал artemis для запуска моего JUNIT, а в prod я использовал очередь oracle. Ниже приведен класс, который я определил для создания connectionFactory.
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
в вашем classpath. Я получил банку от <weblogic_home>\wlserver\server\lib
и создал maven зависимость от jar и толкнул в мое локальное РЕПО и добавил jar как зависимость.
<dependency>
<groupId>com.oracle.weblogic</groupId>
<artifactId>wlthint3client</artifactId>
<version>12.2.1</version>
<scope>provided</scope> <!-- comment out this if you are deploying on tomcat or running the application standalone -->
</dependency>