为了在静态方法中使用自动装配的对象,
通过新建对象(new Object())的方式调用自动装配的对象,
但是,执行时使用自动装配的对象时出现空指针,即新建的对象并没有初始化当前类中的自动装配属性。
异常的样例如下:
package com.monkey.standalone.modules.user.service.impl;
import com.monkey.standalone.modules.user.dao.UserDAO;
import com.monkey.standalone.modules.user.service.IUserService;
import com.monkey.standalone.modules.user.vo.BaseUserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 用户服务实现类.
*
* @author xindaqi
* @date 2021-05-08 16:01
*/
@Service
public class UserServiceImpl implements IUserService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Resource
UserDAO userDAO;
public static void testNew() {
try {
// 只新建了对象,并没有初始化自动装配的属性:userDAO
UserServiceImpl userService = new UserServiceImpl();
// 自动装配的属性userDAO没有初始化,所以userDAO为null
BaseUserVO baseUserVO = userService.userDAO.queryUserById(1);
logger.info(">>>>>>>>>User:{}", baseUserVO);
} catch (Exception ex) {
logger.error(">>>>>>>User error:", ex);
throw new RuntimeException(ex);
}
}
}
异常信息如下图所示,由异常信息可知,使用自动装配的属性userDAO时出现空指针。
2022-11-13 21:11:36,654 ERROR [traceId=, spanId=] 2022-11-13 21:11:36 [http-nio-9122-exec-4] [ERROR] - >>>>>>>User error:
java.lang.NullPointerException: null
at com.monkey.standalone.modules.user.service.impl.UserServiceImpl.testNew(UserServiceImpl.java:46)
at com.monkey.standalone.api.UserApi.queryUserById(UserApi.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
…
通过new新建对象后,并没有初始化对应的属性:userDAO,所以userDAO属性为null,
无法使用该属性对应的其他所有功能。
@Service初始化相关对象时,会交由Spring容器管理,
因此,@Resoure会自动获取Spring会初始化相关对象,userDAO才会生效,
而使用new新建的对象并不会托管给Spring,所以,其他的属性不会自动初始化。
为解决新建对象后相关属性为null的问题,需要在新建对象后初始化相关属性。
为了获取已装配的对象,就要在当前类完成依赖注入之后,执行相关的初始化操作,
而@PostConstructor正是在执行依赖注入之后执行初始化操作的注解,@PostConstruct部分注释如下图所示:
使用@PostConstruct后处理(装配)静态对象。
在当前类中构建静态的当前类属性,
使用@PostConstruct初始化静态的当前类属性,并初始化需要使用的已装配的对象,
完整测试样例如下:
package com.monkey.standalone.modules.user.service.impl;
import com.monkey.standalone.modules.user.dao.UserDAO;
import com.monkey.standalone.modules.user.service.IUserService;
import com.monkey.standalone.modules.user.vo.BaseUserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* 用户服务实现类.
*
* @author xindaqi
* @date 2021-05-08 16:01
*/
@Service
public class UserServiceImpl implements IUserService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
public static UserServiceImpl userServiceImpl;
@Resource
UserDAO userDAO;
@PostConstruct
public void init() {
userServiceImpl = this;
// 初始化已自动装配的对象
userServiceImpl.userDAO = this.userDAO;
}
public static void testAutowired() {
// 通过静态的当前类属性获取相关方法
BaseUserVO baseUserVO = userServiceImpl.userDAO.queryUserById(1);
logger.info(">>>>>>>>>User:{}", baseUserVO);
}
}