Spring @Async @Autowired null 只有一种方法
Spring @Async @Autowired null in only one method
我在我的 Spring 应用程序中调用自动装配对象的方法时遇到 NullPointerException。有问题的 class 如下所示:
@Component
public class Listener {
@Autowired
TemplateService templateService;
@Async
@EventListener
private Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
@Async
@EventListener
public Future<String> listener2(Event2 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
}
当我发布触发 listener1
的事件时,会打印一个 null
值,但是当我发布触发 listener2
的事件时,toString()
方法TemplateService
被调用(如我所料)。我可能误解了 @Async
如何影响 @Autowired
对象的某些方面,但我无法确定那是什么。我在滥用 @Async
吗?我是否误解了如何在多线程环境中使用 @Autowired
对象?
Spring 需要一个接口来创建代理 class。每次调用该方法时都会调用此代理 class,整个异步执行都是通过此方法发生的。没有接口 Spring 无法自动装配、扫描或使方法异步执行。
public interface Listener {
public Future<String> listener1(Event1 event);
public Future<String> listener2(Event2 event);
}
@Component
public class ListenerImpl {
@Autowired
private TemplateService templateService;
@Async
@Override
public Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
@Async
@Override
public Future<String> listener2(Event2 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
}
还值得注意的是 Spring 不能 运行 异步私有方法。
将 listener1 方法的可见性更改为至少受保护(包可见性、受保护或 public)。这是因为 Spring 创建了一个代理,它是您组件的一个子类。它会覆盖您的 @Async 注释方法,以便添加新逻辑以在单独的线程中执行您的代码。但是因为它使用继承它只能覆盖子类可见的方法。
这解释了为什么 public 的 listener2 方法有效。
将您的方法更改为
@Async
@EventListener
public Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
我在我的 Spring 应用程序中调用自动装配对象的方法时遇到 NullPointerException。有问题的 class 如下所示:
@Component
public class Listener {
@Autowired
TemplateService templateService;
@Async
@EventListener
private Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
@Async
@EventListener
public Future<String> listener2(Event2 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
}
当我发布触发 listener1
的事件时,会打印一个 null
值,但是当我发布触发 listener2
的事件时,toString()
方法TemplateService
被调用(如我所料)。我可能误解了 @Async
如何影响 @Autowired
对象的某些方面,但我无法确定那是什么。我在滥用 @Async
吗?我是否误解了如何在多线程环境中使用 @Autowired
对象?
Spring 需要一个接口来创建代理 class。每次调用该方法时都会调用此代理 class,整个异步执行都是通过此方法发生的。没有接口 Spring 无法自动装配、扫描或使方法异步执行。
public interface Listener {
public Future<String> listener1(Event1 event);
public Future<String> listener2(Event2 event);
}
@Component
public class ListenerImpl {
@Autowired
private TemplateService templateService;
@Async
@Override
public Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
@Async
@Override
public Future<String> listener2(Event2 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}
}
还值得注意的是 Spring 不能 运行 异步私有方法。
将 listener1 方法的可见性更改为至少受保护(包可见性、受保护或 public)。这是因为 Spring 创建了一个代理,它是您组件的一个子类。它会覆盖您的 @Async 注释方法,以便添加新逻辑以在单独的线程中执行您的代码。但是因为它使用继承它只能覆盖子类可见的方法。
这解释了为什么 public 的 listener2 方法有效。
将您的方法更改为
@Async
@EventListener
public Future<String> listener1(Event1 event) {
System.out.println(templateService);
return new AsyncResult<>(null);
}