为什么子类的@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 方法来执行此操作,但这没有用,在那种情况下列表没有被初始化.这是为什么?

查看文档并阅读更多内容后,我明白了这里发生的事情:

  1. 因为我的 subclass 被注释为 @Component,PostConstruct 作为 Spring 启动过程的一部分触发,甚至在调用普通构造函数之前.因此,带有 MasterCodeViews 的静态 Map 被填充,并且由于它是静态的,它作为 subclass 静态属性的一部分保持填充。因此,此地图在构建期间具有适当的可用数据。

  2. 当我尝试将 Map 移动到基础 class 时,实际上我将其从子 class 的静态 属性 变为静态属性 of the subclass,这意味着每个构造函数依次用单独的属性填充它,导致地图在大多数情况下都有错误的数据。之后,当我尝试使用 non-static 映射执行此操作时,当我从代码调用构造函数时,数据没有保留,因为这实际上是一个没有初始化组件的新对象。