在使用 @Autowired 做类或接口的自动引入时,可能会出现引入的类为 null 这里我们使用 Spring Boot 来演示几种引发 null 例子。
@Autowired 正常使用
HelloWorldService
package com.mangobeta.test.service;
import org.springframework.stereotype.Service;
@Service
public class HelloWorldService {
public void sayHello(String name) {
System.out.println("Hello " + name);
}
}
HelloWorldServiceTest
package com.mangobeta.test.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HelloWorldServiceTest {
@Autowired
HelloWorldService helloWorldService;
@Test
void sayHello() {
helloWorldService.sayHello("mangobeta");
}
}
@Autowired 引发 Null 几种情况
在静态字段上使用@Autowired
将以下 HelloWorldService 用作 Spring 应用程序中的 bean 会失败,因为不支持对静态字段的依赖项注入。
@SpringBootTest
class HelloWorldServiceTest {
@Autowired
private static HelloWorldService helloWorldService;
@Test
void sayHello() {
helloWorldService.sayHello("mangobeta");
}
}
异常信息:
java.lang.NullPointerException
at com.mangobeta.test.service.HelloWorldServiceTest.sayHello(HelloWorldServiceTest.java:16)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
字段缺省 @Autowired
在Spring应用程序中将下面的 HelloWorldService 用作 Bean 会失败。 由于字段上没有@Autowired(或 @Inject 或 @Resource),因此 Spring 不知道需要将依赖项注入字段。 因此该字段依然为 null。
@SpringBootTest
class HelloWorldServiceTest {
HelloWorldService helloWorldService;
@Test
void sayHello() {
helloWorldService.sayHello("mangobeta");
}
}
Bean 实例对 Sping Bean 不可见
注释为 @Autowired 的字段为 null ,因为 Spring 不知道你用 new 创建的 HelloWorldService 的副本,也不知道要对其自动连接。
新建 MangoBetaService
@Service
public class MangoBetaService {
public void test() {
System.out.println("test");
}
}
HelloWorldService 更改如下
@Service
public class HelloWorldService {
@Autowired
MangoBetaService mangoBetaService;
public void sayHello(String name) {
System.out.println("Hello " + name);
mangoBetaService.test();
}
}
测试
@SpringBootTest
class HelloWorldServiceTest {
// @Autowired
// HelloWorldService helloWorldService;
@Test
void sayHello() {
(new HelloWorldService()).sayHello("mangobeta");
}
}
mangoBetaService 会抛出 NullPointerException 异常