无法让@Resource 注释在 Springboot 中工作
Can't get @Resource annotation to work in Springboot
我一直在使用 Websockets 进行一个项目,我需要在多个 类 和线程中使用相同的 HashMap。阅读了一下后,我发现使用 @Resource 注释是最好的。但是我无法让它工作,并且在打印 String 时我只得到 null,而在使用 ConcurrentHashMap 做任何事情时我得到 NullPointerException。这是部分代码。
SocketHandler.java
@Component
public class SocketHandler extends TextWebSocketHandler {
@Resource(name = "teststring")
private String testString;
private ConcurrentHashMap<WebSocketSession, UserPlayer> sessions;
@Resource(name="sessions")
public void setSessions(ConcurrentHashMap<WebSocketSession, UserPlayer> sessions){
System.out.println("Im in @resource");
this.sessions=sessions;
}
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
System.out.println(testString);
sessions.put(session, new UserPlayer());
System.out.println("Got connection " + session);
}
}
AplicationContextResource.java
@Configuration
public class ApplicationContextResource{
@Bean(name="sessions")
public ConcurrentHashMap<WebSocketSession, UserPlayer> sessions(){
ConcurrentHashMap<WebSocketSession, UserPlayer> sessions = new ConcurrentHashMap<WebSocketSession, UserPlayer>();
System.out.println("bean sessions!!");
return sessions;
}
@Bean(name="teststring")
public String testString(){
String str = new String("12345");
return str;
}
}
BeanPostProc.java
@Configuration
public class BeanPostProc {
@Bean
public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor(){
CommonAnnotationBeanPostProcessor cBeanPostProcessor = new CommonAnnotationBeanPostProcessor();
cBeanPostProcessor.setAlwaysUseJndiLookup(true);
return cBeanPostProcessor;
}
}
这是服务器启动和客户端连接后的控制台输出。
020-05-07 22:03:28.417 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : Starting DemoApplication on Racunalo with PID 3132 (D:\Git\slytherin\server\slith\target\classes started by Sebastijan in d:\Git\slytherin\server\slith)
2020-05-07 22:03:28.421 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : No active profile set, falling back to default profiles: default
2020-05-07 22:03:29.395 INFO 3132 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'beanPostProc' of type [com.soluna.slith.config.BeanPostProc$$EnhancerBySpringCGLIB$4027f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-05-07 22:03:29.758 INFO 3132 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-05-07 22:03:29.771 INFO 3132 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-05-07 22:03:29.772 INFO 3132 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-05-07 22:03:29.874 INFO 3132 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-05-07 22:03:29.875 INFO 3132 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1365 ms
bean sessions!!
Im in @resource
2020-05-07 22:03:30.193 INFO 3132 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-05-07 22:03:30.458 INFO 3132 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-05-07 22:03:30.461 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : Started DemoApplication in 2.511 seconds (JVM running for 3.154)
2020-05-07 22:04:31.705 INFO 3132 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-07 22:04:31.705 INFO 3132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-05-07 22:04:31.722 INFO 3132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 17 ms
null
2020-05-07 22:04:31.808 ERROR 3132 --- [nio-8080-exec-1] w.s.h.ExceptionWebSocketHandlerDecorator : Closing session due to exception for StandardWebSocketSession[id=6aedf417-075a-851d-bb92-16e32ef76915, uri=ws://localhost:8080/game]
java.lang.NullPointerException: null
at com.soluna.slith.controller.SocketHandler.afterConnectionEstablished(SocketHandler.java:65) ~[classes/:na]
我的项目没有 XML,所有示例都显示了基于 XML 的 bean 配置。尝试使用和不使用 .setAlwaysUseJndiLookup(true)。我是否以某种方式弄乱了 CommonAnnotationBeanPostProcessor bean?
在阅读并尝试了很多东西之后,我终于找到了错误。
错误不在上述任何 类 中,而是在 WebSocket 配置中。
BeanPostProc.java CommonAnnotationBeanPostProcessor 甚至不需要。
WebSocket 配置之前:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/game").setAllowedOrigins("*");
}
}
WebSocket 配置现在:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private SocketHandler socketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(socketHandler, "/game").setAllowedOrigins("*");
}
}
错误是我正在创建一个新的 SocketHandler 实例,该实例不受 Spring 管理并且未正确自动装配。
修复错误后,Bean 注入可以使用@Resource 和@Autowired 注释。
我一直在使用 Websockets 进行一个项目,我需要在多个 类 和线程中使用相同的 HashMap。阅读了一下后,我发现使用 @Resource 注释是最好的。但是我无法让它工作,并且在打印 String 时我只得到 null,而在使用 ConcurrentHashMap 做任何事情时我得到 NullPointerException。这是部分代码。
SocketHandler.java
@Component
public class SocketHandler extends TextWebSocketHandler {
@Resource(name = "teststring")
private String testString;
private ConcurrentHashMap<WebSocketSession, UserPlayer> sessions;
@Resource(name="sessions")
public void setSessions(ConcurrentHashMap<WebSocketSession, UserPlayer> sessions){
System.out.println("Im in @resource");
this.sessions=sessions;
}
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
System.out.println(testString);
sessions.put(session, new UserPlayer());
System.out.println("Got connection " + session);
}
}
AplicationContextResource.java
@Configuration
public class ApplicationContextResource{
@Bean(name="sessions")
public ConcurrentHashMap<WebSocketSession, UserPlayer> sessions(){
ConcurrentHashMap<WebSocketSession, UserPlayer> sessions = new ConcurrentHashMap<WebSocketSession, UserPlayer>();
System.out.println("bean sessions!!");
return sessions;
}
@Bean(name="teststring")
public String testString(){
String str = new String("12345");
return str;
}
}
BeanPostProc.java
@Configuration
public class BeanPostProc {
@Bean
public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor(){
CommonAnnotationBeanPostProcessor cBeanPostProcessor = new CommonAnnotationBeanPostProcessor();
cBeanPostProcessor.setAlwaysUseJndiLookup(true);
return cBeanPostProcessor;
}
}
这是服务器启动和客户端连接后的控制台输出。
020-05-07 22:03:28.417 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : Starting DemoApplication on Racunalo with PID 3132 (D:\Git\slytherin\server\slith\target\classes started by Sebastijan in d:\Git\slytherin\server\slith)
2020-05-07 22:03:28.421 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : No active profile set, falling back to default profiles: default
2020-05-07 22:03:29.395 INFO 3132 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'beanPostProc' of type [com.soluna.slith.config.BeanPostProc$$EnhancerBySpringCGLIB$4027f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-05-07 22:03:29.758 INFO 3132 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-05-07 22:03:29.771 INFO 3132 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-05-07 22:03:29.772 INFO 3132 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-05-07 22:03:29.874 INFO 3132 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-05-07 22:03:29.875 INFO 3132 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1365 ms
bean sessions!!
Im in @resource
2020-05-07 22:03:30.193 INFO 3132 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-05-07 22:03:30.458 INFO 3132 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-05-07 22:03:30.461 INFO 3132 --- [ main] com.soluna.slith.DemoApplication : Started DemoApplication in 2.511 seconds (JVM running for 3.154)
2020-05-07 22:04:31.705 INFO 3132 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-07 22:04:31.705 INFO 3132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-05-07 22:04:31.722 INFO 3132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 17 ms
null
2020-05-07 22:04:31.808 ERROR 3132 --- [nio-8080-exec-1] w.s.h.ExceptionWebSocketHandlerDecorator : Closing session due to exception for StandardWebSocketSession[id=6aedf417-075a-851d-bb92-16e32ef76915, uri=ws://localhost:8080/game]
java.lang.NullPointerException: null
at com.soluna.slith.controller.SocketHandler.afterConnectionEstablished(SocketHandler.java:65) ~[classes/:na]
我的项目没有 XML,所有示例都显示了基于 XML 的 bean 配置。尝试使用和不使用 .setAlwaysUseJndiLookup(true)。我是否以某种方式弄乱了 CommonAnnotationBeanPostProcessor bean?
在阅读并尝试了很多东西之后,我终于找到了错误。 错误不在上述任何 类 中,而是在 WebSocket 配置中。 BeanPostProc.java CommonAnnotationBeanPostProcessor 甚至不需要。
WebSocket 配置之前:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/game").setAllowedOrigins("*");
}
}
WebSocket 配置现在:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private SocketHandler socketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(socketHandler, "/game").setAllowedOrigins("*");
}
}
错误是我正在创建一个新的 SocketHandler 实例,该实例不受 Spring 管理并且未正确自动装配。 修复错误后,Bean 注入可以使用@Resource 和@Autowired 注释。