我正尝试在我的消息传递应用程序中使用 @Service 类,但是当我尝试使用通用类时,该类并未通过 @Autowire 实例化。它仅在我使用 Controller 时实例化。
这是我的 Controller :
package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import hello.Application;
@Controller
public class HelloController {
@Autowired
private MessageSender sender;
@RequestMapping(value="/", method=RequestMethod.GET)
public String index() {
return "index";
}
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
System.out.println("Sending message...");
beginRoute(message.getName());
sender.greet("thunder");
return new Greeting("Hello, " + message.getName() + "!");
}
public void beginRoute(String message) {
Application.startBody(message);
}
}
上面对 sender.greet 的调用是成功的。
这是我尝试在其中使用该服务的另一个类:
package com.routing.integration;
import hello.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
@Component
public class modifier {
@Autowired
private MessageSender sender;
public boolean adder(String words) throws Exception {
sender.greet(words);
}
}
当我尝试如上所述调用 sender.greet 时,我得到一个 NullPointerException 并且在调试时,我发现在调用 sender.greet 时 sender 为 null。服务类不是在修饰符中实例化吗?
最后,这里是 MessageSender 服务类:
@Service
public class MessageSender {
@Autowired
private SimpMessagingTemplate template;
@RequestMapping(value="/hello", method=RequestMethod.POST)
public void greet(String greeting) {
Greeting text = new Greeting("Goodbye, " + greeting + "!");
this.template.convertAndSend("/topic/greetings", text);
}
}
如何确保@Autowire 在每个类中实例化 MessageSender?
编辑
这里是调用修改器的地方。它是由 Camel 路线制成的:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:core="http://activemq.apache.org/schema/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/osgi http://camel.apache.org/schema/osgi/camel-osgi.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq:queue:testQSource"/>
<choice>
<when>
<method ref="securityBean"/>
<log message="Routing message from testQSource to testQDestination queue with data ${body}"/>
<to uri="activemq:queue:testQDestination"/>
<to uri="activationBean"/>
<to uri="accountVerificationBean"/>
<to uri="billingCheckingBean"/>
<to uri="deviceConnectorBean"/>
<to uri="deviceActivatorBean"/>
<log message="Account activated: ${body}"/>
</when>
<otherwise>
<log message="message went to stomp: ${body}"/>
</otherwise>
</choice>
</route>
</camelContext>
<camel:camelContext id="camel-client">
<camel:template id="camelTemplate" />
</camel:camelContext>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="browserBean" class="hello.HelloController"/>
<bean id="securityBean" class="com.routing.integration.modifier"/>
<bean id="activationBean" class="com.routing.integration.ActionApp"/>
<bean id="accountVerificationBean" class="com.routing.integration.AccountVerifier"/>
<bean id="billingCheckingBean" class="com.routing.integration.BillingChecker"/>
<bean id="deviceConnectorBean" class="com.routing.integration.DeviceConnector"/>
<bean id="deviceActivatorBean" class="com.routing.integration.DeviceActivator"/>
</beans>
这是堆栈跟踪:
Stacktrace
--------------------------------------------------------------------------------------- ------------------------------------------------
java.lang.NullPointerException
at com.routing.integration.modifier.adder(modifier.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:407)
at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:278)
at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:251)
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:166)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:67)
at org.apache.camel.language.bean.BeanExpression$InvokeProcessor.process(BeanExpression.java:1 89)
at org.apache.camel.language.bean.BeanExpression.evaluate(BeanExpression.java:123)
at org.apache.camel.language.bean.BeanExpression.matches(BeanExpression.java:137)
at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:90)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java: 72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:87)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.ja va:103)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(Abstract MessageListenerContainer.java:562)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMe ssageListenerContainer.java:500)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(Abstrac tMessageListenerContainer.java:468)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecut e(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute( AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.invokeListener(DefaultMessageListenerContainer.java:1102)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.executeOngoingLoop(DefaultMessageListenerContainer.java:1094)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.run(DefaultMessageListenerContainer.java:991)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
WARN : org.apache.camel.component.jms.EndpointMessageListener - Execution of JMS message listener failed. Caused by: [org.apache.camel.RuntimeCamelException - java.lang.NullPointerException]
org.apache.camel.RuntimeCamelException: java.lang.NullPointerException
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1363)
at org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback .done(EndpointMessageListener.java:186)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.ja va:107)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(Abstract MessageListenerContainer.java:562)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMe ssageListenerContainer.java:500)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(Abstrac tMessageListenerContainer.java:468)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecut e(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute( AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.invokeListener(DefaultMessageListenerContainer.java:1102)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.executeOngoingLoop(DefaultMessageListenerContainer.java:1094)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoke r.run(DefaultMessageListenerContainer.java:991)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.routing.integration.modifier.adder(modifier.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:407)
at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:278)
at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:251)
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:166)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:67)
at org.apache.camel.language.bean.BeanExpression$InvokeProcessor.process(BeanExpression.java:1 89)
at org.apache.camel.language.bean.BeanExpression.evaluate(BeanExpression.java:123)
at org.apache.camel.language.bean.BeanExpression.matches(BeanExpression.java:137)
at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:90)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java: 72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:87)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.ja va:103)
... 11 more
编辑 2
这是调用 ComponentScan 的主类:
package hello;
import org.apache.camel.ProducerTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"hello", "com.routing.integration"})
public class Application {
static ApplicationContext context = null;
static ProducerTemplate camelTemplate = null;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.println("----------------------\nSpringBootComplete\n----------------------");
startBody("startup");
}
public static void startBody(String message) {
if (context == null) {
context = new ClassPathXmlApplicationContext("camelspring.xml");
camelTemplate = context.getBean("camelTemplate", ProducerTemplate.class);
}
if (message != "startup"){
camelTemplate.sendBody("activemq:queue:testQSource", message);
}
}
}
最佳答案
您的 Application
类应该如下所示:
@Configuration
@ComponentScan(basePackages = {"hello", "com.routing.integration"})
@EnableAutoConfiguration
@ImportResource("classpath:camel.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
camel.xml
是包含您的 camel 定义的 xml 配置文件。
如果您需要在 xml 配置中定义的任何 bean,例如 xml 中的 camelTemplate
,您可以像这样获取它的引用,例如:
package hello;
import javax.annotation.Resource;
import org.apache.camel.ProducerTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Resource(name="camelTemplate")
private ProducerTemplate template;
@RequestMapping("/")
String home() {
System.out.println(template);
return "Hello World!";
}
}
正如我在评论中所说,不要手动创建应用上下文。使用@Component
、@Service
、@Configuration
和@Bean
等注册你想要的bean。如果你需要在 Java 代码中难以重现的 xml 配置,请使用 @ImportResource
。
在您拥有的 xml 配置文件中,您可以将 browserBean
bean 替换为放置在 hello.HelloController
类上的 @Controller
注释。
您的 activemq
bean 可以在 Java Config 中转换成类似这样的东西:
@Configuration
public class Config {
@Bean
public ActiveMQComponent activemq() {
ActiveMQComponent comp = new ActiveMQComponent();
comp.setBrokerUrl("tcp://localhost:61616");
return comp;
}
}
关于java - @Autowire 调用期间未实例化服务类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24763580/