为什么子类的@PostConstruct 在这种情况下起作用?
Why does the @PostConstruct of the subclass work in this case?
我有以下 Spring Bean 结构:
public abstract class XmlBaseChild {
protected Integer value;
protected String text;
@Autowired
transient protected MasterCodeService masterCodeService;
public XmlBaseChild(Integer value) {
setValue(value);
}
/**
* Set the Numeric value of the ChildView.
* This code is common for all childViews and handles a null value.
* @param value Numeric value of the ChildView
*/
@JsonProperty(value="id")
public void setValue(Integer value) {
if (value == null) {
this.value = null;
this.text = null;
return;
}
setConcreteValue(value);
}
/**
* Set the Numeric value of the ChildView.
* This code must be overridden by the concrete childViews.
* @param value Numeric value of the ChildView
*/
protected void setConcreteValue(Integer value){
boolean keyNotFound = true;
if (value != null && value > -1) {
this.value = value;
String messageKey = getValueFromMap(value, GetMasterCodeMapForChildView());
if (messageKey != null) {
this.text = LocalizeString(messageKey, null, getLocale);
keyNotFound = false;
}
}
if (keyNotFound){
throw new NotFoundException();
}
}
protected abstract Map<String, MasterCodeView> GetMasterCodeMapForChildView();
}
和子class:
@Component
@XmlRootElement(name=XmlDeployTool.VIEW_NAME)
public class XmlDeployTool extends XmlBaseChild {
public static Map<String, MasterCodeView> toolTypeCodes = new HashMap<String, MasterCodeView>();
/**
* Constructor for creating this object and preparing for marchalling (from java objects to xml/json).
* @param value Numeric value of the ChildView
* @param request HttpServletRequest
* @param includeSelf Include SELF link
* @param includeUP Include UP link
*/
public XmlDeployTool(Integer value) {
super(value);
}
/**
* Initialize the Tool Type codes after the component is wired (postconstruct),
* so that they are available in the constructor when an XmlDeploy object is created.
*/
@PostConstruct
protected void initializeDeployToolTypeCodes() {
toolTypeCodes = convertListToMap(masterCodeService.getToolTypeCodes());
}
@Override
protected Map<String, MasterCodeView> GetMasterCodeMapForChildView() {
return toolTypeCodes;
}
}
然而,根据我从其他帖子(如 [=12=)了解到的情况,此处的 @PostConstruct 通常在调用构造函数后执行。那么为什么在构造函数期间填充 toolTypeCodes 映射?这是Spring的@Component注解的一部分吗?
我也尝试使用 XmlBaseChild 中定义的 masterCodeView 映射和 XmlDeployTool class 中定义的 PostConstruct 方法来执行此操作,但这没有用,在那种情况下列表没有被初始化.这是为什么?
查看文档并阅读更多内容后,我明白了这里发生的事情:
因为我的 subclass 被注释为 @Component
,PostConstruct 作为 Spring 启动过程的一部分触发,甚至在调用普通构造函数之前.因此,带有 MasterCodeViews 的静态 Map 被填充,并且由于它是静态的,它作为 subclass 静态属性的一部分保持填充。因此,此地图在构建期间具有适当的可用数据。
当我尝试将 Map 移动到基础 class 时,实际上我将其从子 class 的静态 属性 变为静态属性 of the subclass,这意味着每个构造函数依次用单独的属性填充它,导致地图在大多数情况下都有错误的数据。之后,当我尝试使用 non-static 映射执行此操作时,当我从代码调用构造函数时,数据没有保留,因为这实际上是一个没有初始化组件的新对象。
我有以下 Spring Bean 结构:
public abstract class XmlBaseChild {
protected Integer value;
protected String text;
@Autowired
transient protected MasterCodeService masterCodeService;
public XmlBaseChild(Integer value) {
setValue(value);
}
/**
* Set the Numeric value of the ChildView.
* This code is common for all childViews and handles a null value.
* @param value Numeric value of the ChildView
*/
@JsonProperty(value="id")
public void setValue(Integer value) {
if (value == null) {
this.value = null;
this.text = null;
return;
}
setConcreteValue(value);
}
/**
* Set the Numeric value of the ChildView.
* This code must be overridden by the concrete childViews.
* @param value Numeric value of the ChildView
*/
protected void setConcreteValue(Integer value){
boolean keyNotFound = true;
if (value != null && value > -1) {
this.value = value;
String messageKey = getValueFromMap(value, GetMasterCodeMapForChildView());
if (messageKey != null) {
this.text = LocalizeString(messageKey, null, getLocale);
keyNotFound = false;
}
}
if (keyNotFound){
throw new NotFoundException();
}
}
protected abstract Map<String, MasterCodeView> GetMasterCodeMapForChildView();
}
和子class:
@Component
@XmlRootElement(name=XmlDeployTool.VIEW_NAME)
public class XmlDeployTool extends XmlBaseChild {
public static Map<String, MasterCodeView> toolTypeCodes = new HashMap<String, MasterCodeView>();
/**
* Constructor for creating this object and preparing for marchalling (from java objects to xml/json).
* @param value Numeric value of the ChildView
* @param request HttpServletRequest
* @param includeSelf Include SELF link
* @param includeUP Include UP link
*/
public XmlDeployTool(Integer value) {
super(value);
}
/**
* Initialize the Tool Type codes after the component is wired (postconstruct),
* so that they are available in the constructor when an XmlDeploy object is created.
*/
@PostConstruct
protected void initializeDeployToolTypeCodes() {
toolTypeCodes = convertListToMap(masterCodeService.getToolTypeCodes());
}
@Override
protected Map<String, MasterCodeView> GetMasterCodeMapForChildView() {
return toolTypeCodes;
}
}
然而,根据我从其他帖子(如 [=12=)了解到的情况,此处的 @PostConstruct 通常在调用构造函数后执行。那么为什么在构造函数期间填充 toolTypeCodes 映射?这是Spring的@Component注解的一部分吗?
我也尝试使用 XmlBaseChild 中定义的 masterCodeView 映射和 XmlDeployTool class 中定义的 PostConstruct 方法来执行此操作,但这没有用,在那种情况下列表没有被初始化.这是为什么?
查看文档并阅读更多内容后,我明白了这里发生的事情:
因为我的 subclass 被注释为
@Component
,PostConstruct 作为 Spring 启动过程的一部分触发,甚至在调用普通构造函数之前.因此,带有 MasterCodeViews 的静态 Map 被填充,并且由于它是静态的,它作为 subclass 静态属性的一部分保持填充。因此,此地图在构建期间具有适当的可用数据。当我尝试将 Map 移动到基础 class 时,实际上我将其从子 class 的静态 属性 变为静态属性 of the subclass,这意味着每个构造函数依次用单独的属性填充它,导致地图在大多数情况下都有错误的数据。之后,当我尝试使用 non-static 映射执行此操作时,当我从代码调用构造函数时,数据没有保留,因为这实际上是一个没有初始化组件的新对象。