RabbitMQ春季启动会话错误 [英] RabbitMQ Spring Boot Session Error

查看:104
本文介绍了RabbitMQ春季启动会话错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试将RabbitMQ队列消息传递到我的Spring Boot应用程序时遇到问题.我正在运行spring data 4,并且正在使用Neo4j作为数据库.我能够从RabbitMQ队列接收并解析JSON字符串到Spring Boot应用程序.这是接收器进程的线程更改:

I am running into an issue when trying to pass a RabbitMQ queue message to my Spring Boot application. I am running spring data 4 and am using Neo4j as my database. I am able to recieve and parse a JSON string from the RabbitMQ queue to the spring boot app. Here is the thread change for the receiver process:

14:19:17.811 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8080 (http) 14:19:17.813 [main] INFO org.directoryx.Application - Started Application in 4.989 seconds (JVM running for 5.47) 14:19:26.708 [SimpleAsyncTaskExecutor-1] INFO org.directoryx.sync.Receiver - Message Recv'd! {"lastName":"Okuneva", "country":"United States", "city":"New Stantonfort","org":"IT","photo":"profile9.jpg", "active":"true", "managerId":"1502", "title":"Global Integration Orchestrator", "userId":"frokune", "firstName":"Frank", "phone":"(485)544-1782 x913", "id":"6791", "email":"frokune@peoplemaker.com","status":"Employee"} 14:19:26.718 [SimpleAsyncTaskExecutor-1] INFO org.directoryx.sync.Receiver - Update Person: Frank Okuneva

14:19:17.811 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8080 (http) 14:19:17.813 [main] INFO org.directoryx.Application - Started Application in 4.989 seconds (JVM running for 5.47) 14:19:26.708 [SimpleAsyncTaskExecutor-1] INFO org.directoryx.sync.Receiver - Message Recv'd! {"lastName":"Okuneva", "country":"United States", "city":"New Stantonfort","org":"IT","photo":"profile9.jpg", "active":"true", "managerId":"1502", "title":"Global Integration Orchestrator", "userId":"frokune", "firstName":"Frank", "phone":"(485)544-1782 x913", "id":"6791", "email":"frokune@peoplemaker.com","status":"Employee"} 14:19:26.718 [SimpleAsyncTaskExecutor-1] INFO org.directoryx.sync.Receiver - Update Person: Frank Okuneva

但是当我尝试将传入的JSON保存到Neo4j节点时,应用程序崩溃并出现以下错误:

but when I try to save the incoming JSON into a Neo4j node, the application crashes with the following error:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'receiver': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.neo4j.template.Neo4jTemplate

在实现neo4jTemplate之前,我尝试通过我的personService-> personServiceImpl-> personRepository模式保存该人时遇到此错误.

Before implementing the neo4jTemplate I was getting this error when I tried to save the person through my personService->personServiceImpl->personRepository pattern.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.getSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

这里涉及三个类别:

Receiver.java

@Service
public class Receiver implements MessageListener {

static Logger log = LoggerFactory.getLogger(Receiver.class);

// Fails to be injected...
// Injection of autowired dependencies failed; nested exception is
// org.springframework.beans.factory.BeanCreationException: Could not autowire field:
@Autowired
private Neo4jTemplate neo4jTemplate;

public void onMessage(Message message) {
    Gson gson  = new GsonBuilder().create();
    String msg = new String(message.getBody());
    log.info("Message Recv'd! {}",msg);

    Person person = gson.fromJson(msg, Person.class);
    log.info("Update Person: {} {}", person.getFirstName(), person.getLastName());

    try {
        neo4jTemplate.save(person);
    } catch (Exception e) {
        log.error("Receiver failed to save Person: {}", e);
    }
}

DataSyncConfig.java

@Configuration
public class DataSyncConfig {


@Autowired
RabbitTemplate rabbitTemplate;
private final String QUEUE_NAME = "sync2";
private final String ROUTING_KEY = "routeme";
private final boolean DURABLE = true;
private final boolean EXCLUSIVE = true;
private final boolean AUTO_DELETE = true;

@Bean
Queue queue() {
    return new Queue(QUEUE_NAME, DURABLE, !EXCLUSIVE, !AUTO_DELETE);
}

@Bean
TopicExchange exchange() {
    return new TopicExchange("etl-sync-tool");
}

@Bean
Binding binding(Queue queue, TopicExchange exchange) {
    return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);
}

@Bean
public MessageConverter jsonMessageConverter() {
    JsonMessageConverter jsonMessageConverter = new JsonMessageConverter();
    return jsonMessageConverter;
}

@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames(QUEUE_NAME);
    container.setMessageListener(listenerAdapter);
    return container;
}

@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
    return new MessageListenerAdapter(receiver);
}
}

Neo4jConfig.java

@Configuration
@EnableNeo4jRepositories(basePackages = "org.directoryx.repository", queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND)
@EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {

private final Logger log = LoggerFactory.getLogger(Neo4jConfig.class);

@Resource
public Environment env;

@Override
@Bean
public Neo4jServer neo4jServer() {
    log.info("Initialising Neo4j server connection...");

    // username and password need to be available as System properties for Neo4j authentication.
    String user = env.getProperty("neo4j.user");
    System.setProperty("username", user);

    String pass = env.getProperty("neo4j.pass");
    System.setProperty("password", pass);

    log.info("connecting as neo4j.user=" + user);
    return new RemoteServer("http://localhost:7474");
}

@Override
@Bean
public SessionFactory getSessionFactory() {
    log.info("Initialising Session Factory");
    return new SessionFactory("org.directoryx.domain");
}

@Override
@Bean
// Unsure of scope value, tried both "session" and "global"
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
    log.info("Initialising session-scoped Session Bean");
    return super.getSession();
}

@Bean
public Neo4jTemplate neo4jTemplate (Session session ) {
    return new Neo4jTemplate(session);
}
}

我似乎无法通过公开和使用当前线程,或者通过创建新线程来找到如何将数据保存到db的方法.我觉得这个问题与Spring Boot和Spring Data的某些核心功能应该相距不远,但是即使经过大量研究,我似乎也无法确定要使用哪种语法.

I can't seem to find out how to save the data to the db either by exposing and using the current thread or by creating a new thread. I feel that this is an issue that shouldn't be far off from some of the core functionality of Spring Boot and Spring Data, but I cant seem to determine what syntax to use even after extensive research.

推荐答案

该错误消息表明,在您的使用上下文中不适合使用会话范围运行,这可能是因为您在RabbitMQ上下文中而不是在Spring中Web/MVC一个.

The error message suggests that running with a session scope isn't appropriate in your usage context, probably because you're in a RabbitMQ context as opposed to a Spring Web/MVC one.

我建议从Neo4jConfig中的getSession方法中完全删除@Scope批注,看看是否有改善.如果有必要,您以后总是可以添加用户管理的作用域.

I'd advise removing the @Scope annotation altogether from your getSession method in Neo4jConfig and see if that improves things. You can always add a user-managed scope later if you feel it's necessary to do so.

此外,您可能需要考虑针对Neo4jOperations而不是Neo4jTemplate进行编码.一些用户报告了注入类而不是接口的问题.

In addition, you may want to consider coding against Neo4jOperations instead of Neo4jTemplate. Some users have reported problems with injecting the class instead of the interface.

这篇关于RabbitMQ春季启动会话错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆