请考虑以下情形:
public class Car {
@Inject
private Engine engine;
public Car() {
engine.initialize();
}
...
}
由于Car必须在字段注入之前进行实例化,因此注入点引擎在构造函数执行期间仍为null,从而导致NullPointerException。
这个问题可以通过Java构造函数注入的JSR-330依赖注入或Java @PostConstruct方法注释的JSR 250 Common Annotations来解决。
@PostConstruct
JSR-250定义了一组通用的注释,这些注释已包含在Java SE 6中。
PostConstruct注释用于需要的方法 在完成依赖注入以执行任何操作之后执行 初始化。 必须在放入类之前调用此方法 投入使用。 所有类都必须支持此注释 支持依赖注入。
JSR-250 Chap。 2.5 javax.annotation.PostConstruct
@PostConstruct注释允许在实例化实例并且已执行所有注入之后定义要执行的方法。
public class Car {
@Inject
private Engine engine;
@PostConstruct
public void postConstruct() {
engine.initialize();
}
...
}
代码不是在构造函数中执行初始化,而是移动到使用@PostConstruct注释的方法。
后构造方法的处理很简单,只需查找使用@PostConstruct注释的所有方法并依次调用它们即可。
private void processPostConstruct(Class type, T targetInstance) {
Method[] declaredMethods = type.getDeclaredMethods();
Arrays.stream(declaredMethods)
.filter(method -> method.getAnnotation(PostConstruct.class) != null)
.forEach(postConstructMethod -> {
try {
postConstructMethod.setAccessible(true);
postConstructMethod.invoke(targetInstance, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
});
}
必须在实例化和注入完成后执行后构造方法的处理。