在日常项目开发中,单例模式可以说是最常用到的设计模式,项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能。通常可能会使用 @Resource 或者 @Autowired 来自动注入实例,然而这种方法在单例模式中却会出现 NullPointException 的问题。那么本篇就此问题做一下研究。
问题初探
一般我们的项目是分层开发的,最经典的可能就是下面这种结构:1
2
3├── UserDao -- DAO 层,负责和数据源交互,获取数据。
├── UserService -- 服务逻辑层,负责业务逻辑实现。
└── UserController -- 控制层,负责提供与外界交互的接口。
此时需要一个单例对象,此对象需要 UserService 来提供用户服务。代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27@Slf4j
public class UserSingleton{
private static volatile UserSingleton INSTANCE;
@Resource
private UserService userService;
public static UserSingleton getInstance(){
if (null == INSTANCE) {
synchronized (UserSingleton.class) {
if (null == INSTANCE) {
INSTANCE = new UserSingleton();
}
}
}
return INSTANCE;
}
public String getUser(){
if (null == userService) {
log.debug("UserSingleton userService is null");
return "UserSingleton Exception: userService is null";
}
return userService.getUser();
}
}
然后创建一个 UserController 来调用 UserSingleton.getUser() 方法看看返回数据是什么。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26@RestController
public class UserController{
@Resource
private UserService userService;
/**
* 正常方式,在 Controller 自动注入 Service。
*
* @return user info
*/
@GetMapping("/user")
public String getUser(){
return userService.getUser();
}
/**
* 使用单例对象中自动注入的 UserService 的方法
*
* @return UserSingleton Exception: userService is null
*/
@GetMapping("/user/singleton/ioc")
pub