Почему @PostConstruct подкласса работает в этом случае? - PullRequest
0 голосов
/ 21 мая 2019

У меня есть следующая структура 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();
}

И подкласс:

@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;
    }
}

Однако из того, что я понимаю из других сообщений, таких как Order of @PostConstructи наследование , @PostConstruct здесь обычно выполняется ПОСЛЕ вызова конструктора.Тогда почему карта toolTypeCodes заполняется во время конструктора?Является ли это частью аннотации @Component Spring?

Я также попытался сделать это с картой masterCodeView, определенной в XmlBaseChild, и только с методом PostConstruct, определенным в классе XmlDeployTool, но это не сработало, списокне получил инициализацию в этом случае.Почему это?

1 Ответ

0 голосов
/ 22 мая 2019

После проверки документации и прочтения, я выяснил, что здесь происходит:

  1. Поскольку мой подкласс помечен @Component, PostConstruct срабатывает как частьВесенний процесс запуска, даже перед любыми вызовами обычного конструктора.Из-за этого заполняется статическая карта с MasterCodeViews, и, поскольку она является статической, она остается заполненной как часть статических свойств подкласса.Из-за этого у этой карты есть правильные пригодные для использования данные во время построения.

  2. Когда я попытался переместить Карту в базовый класс, фактически я превратил это из статического свойства подкласса.статическому свойству подкласса, что означало, что каждый конструктор, в свою очередь, заполнял его отдельными свойствами, что приводило к тому, что карта большую часть времени имела неправильные данные.Когда после этого я попытался сделать это с нестатической картой, данные не были сохранены, когда я вызвал конструктор из кода, потому что это был фактически новый объект без инициализированных компонентов.

...