рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реНрдЯреЗрдЯрдореИрдЪ рд╢реБрд░реВ рдХрд░реЗрдВ

рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐


рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдореИрдВ рддреАрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдорд┐рд▓рд╛, рдПрдХ рд░рд╛рд╕реНрддрд╛ рдпрд╛ рдХреЛрдИ рджреВрд╕рд░рд╛ рдЬреЛ рдкрд░рд┐рдорд┐рдд рдСрдЯреЛрдореЗрдЯрд╛ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕реЗ рдЬреБрдбрд╝рд╛ рдерд╛

  • рдЙрджрд╛рд╣рд░рдг 1. рдПрдХ рдордиреЛрд░рдВрдЬрдХ govnokod рдХреЛрдб ред рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдХреЛрдб рдореЗрдВ рд╕рдВрдХреЗрддрд┐рдд рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрд╡рддрд╛рд░ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдПрдХ рдмрд▓реНрдХрд┐ рднрдпрдВрдХрд░ рдбрдВрдк рд╣реИ рдЬреЛ рдХрднреА-рдХрднреА рдмреЗрддрд╣рд╛рд╢рд╛ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдХреЛрдб рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдХреЛрдб рдХрд╛ рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг рдмреЗрд╣рддрд░ рд╣реИ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЫреВрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд░ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреАрд╡рд┐рджреН, рдХрд╛рд░реНрдпрдкреНрд░рдгрд╛рд▓реА рдФрд░ рдЙрддреНрдкрд╛рдж рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред рд╡реЗ рдЖрдкрд╛рддрдХрд╛рд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреБрдЫ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХреЛрдб рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ (рдЬрдм рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ), рдХрд┐рд╕реА рднреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк рджреЗрдиреЗ рдХрд╛ рдХреЛрдИ рд╕рд╡рд╛рд▓ рдирд╣реАрдВ рд╣реИред рдЗрд╕реЗ рддреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд░рд╛рд╡рдирд╛ рд╣реИред рджреВрд╕рд░реА рд╣рдбрд╝рддрд╛рд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЕрд▓рдЧ рдХрд░рддреА рд╣реИ, рдРрд╕реЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕реНрд╡рд┐рдЪ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИ, рдкреВрд░реНрдг рд╕реНрдХреНрд░реАрдиред
    рдЗрд╕ рд╕реНрдХреЛрд░ рдкрд░ рднреА рдПрдХ рдордЬрд╛рдХ рд╣реИ:
    рдЗрд╖реНрдЯрддрдо рдЖрдХрд╛рд░
    JPoint рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░, рд╡рдХреНрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ, рд╢рд╛рдпрдж рдирд┐рдХреЛрд▓рд╛рдИ рдЕрд▓рд┐рдореЗрдирдХреЛрд╡, рдиреЗ рд╕реНрд╡рд┐рдЪ рдореЗрдВ рдХрд┐рддрдиреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рд╣реИ, рдиреЗ рдХрд╣рд╛ рдХрд┐ рд╢реАрд░реНрд╖ рдЙрддреНрддрд░ "рдЕрдм рддрдХ рд╕реНрдХреНрд░реАрди рдореЗрдВ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИред" рддрджрдиреБрд╕рд╛рд░, рдпрджрд┐ рдЖрдк рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХрд╛ рд╕реНрд╡рд┐рдЪ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдИрдбреАрдИ рдореЗрдВ рдлрд╝реЙрдиреНрдЯ рдЖрдХрд╛рд░ рд▓реЗрдВ рдФрд░ рдХрдо рдХрд░реЗрдВ
  • рдЙрджрд╛рд╣рд░рдг 2. рдкреИрдЯрд░реНрди рд╕реНрдЯреЗрдЯ ред рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ (рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рд▓рд┐рдВрдХ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ) рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡реНрдпрд╛рдкрд╛рд░ рдХрд╛рд░реНрдп рдХреЛ рдЕрдВрддрд┐рдо рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рд╕реЗрдЯ рдореЗрдВ рддреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рдЙрдирдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред
    рдкреИрдЯрд░реНрди рд╕реНрдЯреЗрдЯ рдХрд╛ рдореБрдЦреНрдп рджреЛрд╖ рдпрд╣ рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╡реЗ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рднрд╛рдИ рд╣реИрдВ рдФрд░ рдПрдХ-рджреВрд╕рд░реЗ рдХреЛ рдмреБрд▓рд╛рддреЗ рд╣реИрдВред рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХрд╛рдлреА рдХрдард┐рди рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рднреБрдЧрддрд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рднреБрдЧрддрд╛рди рдкреНрд░рдгрд╛рд▓реА рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдЬреЗрдиреЗрд░рд┐рдХ-рдПрд╕ рдореЗрдВ рдЦреБрджрд╛рдИ рдХрд░рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдЗрддрдирд╛ рдмрдврд╝рд╛ рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЗ рддрд░реАрдХреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛ рд╕рдХрддреА рд╣реИ:

    private < T extends BaseContextPayment, Q extends BaseDomainPaymentRequest, S, B extends AbstractPaymentDetailBuilder<T, Q, S, B>, F extends AbstractPaymentBuilder<T, Q, S, B> > PaymentContext<T, S> build(final Q request, final Class<F> factoryClass){ //""  } 

    рд╕рд╛рд░рд╛рдВрд╢рд┐рдд рд░рд╛рдЬреНрдп: рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрд▓реНрдХрд┐ рдЬрдЯрд┐рд▓ рдХреЛрдб рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • рдЙрджрд╛рд╣рд░рдг 3 StateMachine рдкреИрдЯрд░реНрди рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдпреЛрдВ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдкрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдВрдХреНрд░рдордг рдирд┐рдпрдВрддреНрд░рдг рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдмреЗрд╣рддрд░, рдХрдо рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдХреЛрдб рд╕рд░рд▓ рд╣реИред

рдкрд╣рд▓реЗ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рднреА "рд╢рдХреНрддрд┐" рдФрд░ рджреВрд╕рд░реЗ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХрд╛ рдЕрдиреБрднрд╡ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдордиреЗ рдирдП рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдкреИрдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореИрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреЗрдЯрдореИрдЪрд┐рди рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреЛ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ (рдпрд╣ рд╕реНрдкреНрд░рд┐рдВрдЧ рд╣реИ)ред

рдбреЙрдХ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ YouTube рдФрд░ Habr рдЧрдпрд╛ (рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд▓реЛрдЧ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдХреИрд╕реЗ рдареЗрд╕ рдкрд░ рдорд╣рд╕реВрд╕ рдХрд░рддрд╛ рд╣реИ, рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рд░реЗрдХ рд╣реИ, рдЖрджрд┐) рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдереЛрдбрд╝реА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ, YouTube рдкрд░ рдХреБрдЫ рд╡реАрдбрд┐рдпреЛ рд╣реИрдВ, рд╕рднреА рдХрд╛рдлреА рд╕рддрд╣реА рд╣реИрдВред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ Habr├й рдкрд░ рдореБрдЭреЗ рдХреЗрд╡рд▓ рдПрдХ рд▓реЗрдЦ рдорд┐рд▓рд╛, рд╕рд╛рде рд╣реА рд╕рд╛рде рд╡реАрдбрд┐рдпреЛ, рдХрд╛рдлреА рд╕рддрд╣реАред
рдПрдХ рд▓реЗрдЦ рдореЗрдВ, рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реНрдЯреЗрдЯрдорд╛рдЗрди рдХреЗ рдХрд╛рдо рдХреА рд╕рднреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛, рдбреЙрдХ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдирд╛ рдФрд░ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдФрд░ рдорд╛рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рдФрд░ рд░реЗрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдореЗрд░реЗ рдмрд╛рд░реЗ рдореЗрдВ, рдЬрдм рдореИрдВ рдврд╛рдВрдЪреЗ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рдЧрдпрд╛, рддреЛ рдиреАрдЪреЗ рджреА рдЧрдИ рдЬрд╛рдирдХрд╛рд░реАред рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рд╣реЛрдЧрд╛ред

рдореБрдЦреНрдп рд╢рд░реАрд░


рд╣рдо рдПрдХ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВрдЧреЗ, рдПрдХ рд╡реЗрдм рд╕реНрдЯрд╛рд░реНрдЯрд░ рдЬреЛрдбрд╝реЗрдВрдЧреЗ (рд╣рдо рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓рд╛ рд░рд╣реЗ рд╣реИрдВ)ред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЦрд░реАрдж рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдПрдХ рдЕрдореВрд░реНрдд рд╣реЛрдЧрд╛ред рдЦрд░реАрдж рдкрд░ рдЙрддреНрдкрд╛рдж рдирдП, рдЖрд░рдХреНрд╖рд┐рдд, рдЖрд░рдХреНрд╖рд┐рдд рдЧрд┐рд░рд╛рд╡рдЯ рдФрд░ рдЦрд░реАрдж рдкреВрд░реНрдг рдХреЗ рдЪрд░рдгреЛрдВ рд╕реЗ рдЧреБрдЬрд░реЗрдЧрд╛ред
рдереЛрдбрд╝рд╛ рд╕рд╛ рд╕реБрдзрд╛рд░, рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреА, рд▓реЗрдХрд┐рди рдареАрдХ рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдмрд╣реБрдд рд╣реА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИред
рдирдП рдмреЗрдХреНрдб рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ pom.xml рдореЗрдВ, рдорд╢реАрди рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ (рд╡реЗрдм тАЛтАЛрд╕реНрдЯрд╛рд░реНрдЯрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдЧрд░ start.spring.io рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ):
 <dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-core</artifactId> <version>2.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-test</artifactId> <version>2.1.3.RELEASE</version> <scope>test</scope> </dependency> <cut /> 

рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдБ:

рдореБрдЭреЗ рдЕрднреА рддрдХ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирд╛ рд╣реИ, рдореИрдВ рд╕рдм рдХреБрдЫ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рд╕рдордЭрд╛рдКрдВрдЧрд╛, рдФрд░ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реНрд░реЛрдд рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд╣реЛрдЧрд╛ред

рддреЛ рдЪрд▓рд┐рдП рдЪрд▓рддреЗ рд╣реИрдВред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрд╡рд╢реНрдпрдХ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрд╡рдЪреНрдЫ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ, рдПрдХ рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рд╣рдо рд░рд╛рдЬреНрдп рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде, рдПрдХ рд╕рд░рд▓ рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рд╕рд╛рде, рджреБрд╢реНрдордиреА рдкреИрджрд╛ рдХрд░реЗрдВрдЧреЗ, рдпреЗ рдШрдЯрдХ рд╕реНрд╡рдпрдВ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВред
 public enum PurchaseEvent { RESERVE, BUY, RESERVE_DECLINE } 

 public enum PurchaseState { NEW, RESERVED, CANCEL_RESERVED, PURCHASE_COMPLETE } 

рдпрджреНрдпрдкрд┐ рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдЗрди рдПрдирдо рдореЗрдВ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЙрдирдореЗрдВ рдХреБрдЫ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдЗрд╕рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд┐рд╢реЗрд╖ рд░рд╛рдЬреНрдп, рдЬреЛ рдХрд╛рдлреА рддрд╛рд░реНрдХрд┐рдХ рд╣реИ (рд╣рдордиреЗ рдЕрдкрдиреЗ рдорд╛рдорд▓реЗ рдХреЛ рд╣рд▓ рдХрд░рдХреЗ, рдХрд╛рдлреА рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд┐рдпрд╛)ред
рд╣рдо java config рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдорд╢реАрди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВрдЧреЗ, рд╡рд┐рдиреНрдпрд╛рд╕ рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВрдЧреЗ рдФрд░, рдХреНрд▓рд╛рд╕ EnumStateMachineConfigurerAdapter <PurchaseState, PurchaseEvent> рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдПред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░рд╛ рд░рд╛рдЬреНрдп рдФрд░ рдШрдЯрдирд╛ enum рд╣реИ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЙрдкрдпреБрдХреНрдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБ рдХреЛ рдЬреЗрдиреЗрд░рд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╣рдо рд▓реЗрдЦ рдореЗрдВ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ EnumStateMachineConfigurerAdapter рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ)ред

рдЕрдЧрд▓рд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдПрдХ рдорд╢реАрди рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЬреАрд╡рд┐рдд рд░рд╣реЗрдЧреА: @EnableStateMachine рдХреЗ рдПрдХрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╛ рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ @EnableStateMachineFactory рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рдПрдХ рдмрд╣реБ-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ, рддреЛ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдЖрдкрдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж рд╣реА рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рджреВрд╕рд░реЗ рдХреЛ рдЕрдзрд┐рдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред StateMachine рдХреЛ рдмрд┐рд▓реНрдбрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдирд┐рдпрдорд┐рдд рдмреАрди рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦреЗрдВ), рдЬреЛ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдорд╢реАрди рдХреЛ рдмреАрди рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ), рдФрд░ рдпрджрд┐ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдмреАрди рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЕрдкрдирд╛ рджрд╛рдпрд░рд╛ рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЬреИрд╕реЗ рд╕рддреНрд░ рдпрд╛ рдЕрдиреБрд░реЛрдзред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд░реИрдкрд░ (рд╣рдорд╛рд░реЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ) рдХреЛ рд╕реНрдЯреЗрдЯрдорд╛рдЗрди рдмреАрди рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд░реИрдкрд░ рд╕рд┐рдВрдЧрд▓рдЯрди рдерд╛, рдФрд░ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдорд╢реАрди рднреА
рдЬреЗрд▓реА
рд╕рд┐рдВрдЧреНрд▓рдЯрди рдореЗрдВ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ?
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдкрдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд░ рдмрд╛рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рдирдХреЗрдирдЯреЗрдХреНрд╕реНрдЯ рд╕реЗ рдПрдХ рдирдпрд╛ рдмреАрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЬрд┐рдХ рдХреЛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ рдПрдХ рдкрд╛рдк рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдмреАрди рд╕реНрдЯреЗрдЯрдорд╛рдЗрди рдХреЛ рдпрд╛ рддреЛ рдХрдо рд╕реЗ рдХрдо рдПрдХ рд╡рд┐рдзрд┐, рдпрд╛ рдПрдХ рд╕рд╛рд░ рд╡рд┐рдзрд┐ (рд╡рд┐рдзрд┐ рдЗрдВрдЬреЗрдХреНрд╢рди) рдХреЗ рд╕рд╛рде рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрдм рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕рдВрдХреЗрддрд┐рдд рд╕рд╛рд░ рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣рдо рд╕реЗ рдЦреАрдВрдЪ рд▓реЗрдВрдЧреЗред applicationContext рдирдпрд╛ рдмреАрдиред рдпрд╣ рд╡рд┐рдиреНрдпрд╛рд╕ рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рдирдХрдиреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд╣реЛрдирд╛ рд╕рд╛рдорд╛рдиреНрдп рдЕрднреНрдпрд╛рд╕ рд╣реИ, рдФрд░ рдЕрдореВрд░реНрдд рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо .getBean () рдХрд╣реЗрдВрдЧреЗ;

EnumStateMachineConfigurerAdapter рдХреНрд▓рд╛рд╕ рдореЗрдВ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рдУрд╡рд░рд░рд╛рдЗрдбрд┐рдВрдЧ рдЬрд┐рд╕рд╕реЗ рд╣рдо рдорд╢реАрди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдерд┐рддрд┐ рджрд░реНрдЬ рдХрд░реЗрдВ:
  @Override public void configure(final StateMachineStateConfigurer<PurchaseState, PurchaseEvent> states) throws Exception { states .withStates() .initial(NEW) .end(PURCHASE_COMPLETE) .states(EnumSet.allOf(PurchaseState.class)); } 

рдкреНрд░рд╛рд░рдВрднрд┐рдХ (рдирдпрд╛) рд╡рд╣ рд╕реНрдерд┐рддрд┐ рд╣реИ рдЬреЛ рдорд╢реАрди рдмреАрди рдХреЗ рдмрдирдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛрдЧреА, рдЕрдВрдд (PURCHASE_COMPLETE) рд╡рд╣ рд╕реНрдерд┐рддрд┐ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдорд╢реАрди рдПрдХ рдЧреИрд░-рдирд┐рд░реНрдзрд╛рд░рдХ рдорд╢реАрди рдХреЗ рд▓рд┐рдП Statemachine.stop () рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреА рд╣реИ, (рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред .states (EnumSet.allOf (PurchaseState.class) рд╕рднреА рд╕реНрдЯреЗрдЯрд╕ рдХреА рд╕реВрдЪреА, рдЖрдк рдереЛрдХ рдореЗрдВ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВред

рд╡реИрд╢реНрд╡рд┐рдХ рдорд╢реАрди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
  @Override public void configure(final StateMachineConfigurationConfigurer<PurchaseState, PurchaseEvent> config) throws Exception { config .withConfiguration() .autoStartup(true) .listener(new PurchaseStateMachineApplicationListener()); } 

рдпрд╣рд╛рдВ рдСрдЯреЛрд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдорд╢реАрди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧреА, рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ - рдЪрд╛рд╣реЗ рд╡рд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдирдИ рд╕реНрдерд┐рддрд┐ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЧрд▓рдд) рдкрд░ рд╕реНрд╡рд┐рдЪ рд╣реЛ рдЬрд╛рдПрдЧреАред рддреБрд░рдВрдд, рд╣рдо рдорд╢реАрди рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдПрдХ рд╢реНрд░реЛрддрд╛ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рддреЗ рд╣реИрдВ (рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж), рдЙрд╕реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдЖрдк рдПрдХ рдЕрд▓рдЧ рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрдирдХрд░реНрддрд╛ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдЬрдм рдЙрдирдХреЗ рдХреБрдЫ рдмрджрд▓рд╛рд╡реЛрдВ рдкрд░ рдПрдХ рд▓рдВрдмреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдЖрд╡реЗрджрди рдЖрдЧреЗ рднреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдареАрдХ рд╣реИ, рд╕рдВрдХреНрд░рдордг рдЦреБрдж:
  @Override public void configure(final StateMachineTransitionConfigurer<PurchaseState, PurchaseEvent> transitions) throws Exception { transitions .withExternal() .source(NEW) .target(RESERVED) .event(RESERVE) .action(reservedAction(), errorAction()) .and() .withExternal() .source(RESERVED) .target(CANCEL_RESERVED) .event(RESERVE_DECLINE) .action(cancelAction(), errorAction()) .and() .withExternal() .source(RESERVED) .target(PURCHASE_COMPLETE) .event(BUY) .guard(hideGuard()) .action(buyAction(), errorAction()); } 

рд╕рдВрдХреНрд░рдордг рдпрд╛ рд╕рдВрдХреНрд░рдордг рдХреЗ рд╕рднреА рддрд░реНрдХ рдпрд╣рд╛рдВ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдЧрд╛рд░реНрдб рдХреЛ рд╕рдВрдХреНрд░рдордгреЛрдВ рдкрд░ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рдШрдЯрдХ рдЬреЛ рд╣рдореЗрд╢рд╛ рдмреВрд▓рд┐рдпрди рджреЗрддрд╛ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдк рдЕрдкрдиреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рдПрдХ рд╕реНрдерд┐рддрд┐ рд╕реЗ рджреВрд╕рд░реЗ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ, рдХреЛрдИ рднреА рддрд░реНрдХ рдЧрд╛рд░реНрдб рдореЗрдВ рдкрд░рд┐рдкреВрд░реНрдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╛рдзрд╛рд░рдг рдШрдЯрдХ рд╣реИ рд▓реЗрдХрд┐рди рдЙрд╕реЗ рдмреВрд▓рд┐рдпрди рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, HideGuard рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реЗрдЯрд┐рдВрдЧ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рдЗрд╕ рдЙрддреНрдкрд╛рдж рдХреЛ рди рджрд┐рдЦрд╛рдПрдВ) рдФрд░, рдЗрд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЧрд╛рд░реНрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рд░рд╛рдЬреНрдп рдореЗрдВ рдорд╢реАрди рдХреЛ рди рджреЗрдВред рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЧрд╛рд░реНрдб, рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╡рд┐рдиреНрдпрд╛рд╕ рдореЗрдВ рдПрдХ рд╕рдВрдХреНрд░рдордг рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдРрд╕рд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:
  .withExternal() .source(RESERVED) .target(PURCHASE_COMPLETE) .event(BUY) .guard(hideGuard()) .guard(veryHideGuard()) 

рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкрд╣рд▓рд╛ рдЧрд╛рд░реНрдб (рдЫрд┐рдкрд╛рдирд╛) ()
рд▓реЗрдХрд┐рди рдЖрдк рдХрдИ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрдм рд╣рдо рдПрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо рд╕рдВрдХреНрд░рдордг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ), рдореИрдВрдиреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рддреАрди рд╕рдВрдХреНрд░рдордгреЛрдВ рдХреЛ рдПрдХ рд╕рдВрдХреНрд░рдордг рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИред
  .withExternal() .source(NEW) .target(RESERVED) .event(RESERVE) .action(reservedAction(), errorAction()) 

рджреВрд╕рд░рд╛ рддрд░реНрдХ рд╣реИ рдПрд░рд░рдПрдХреНрд╢рди, рдЕрдЧрд░ рд░рд┐рдЬрд░реНрд╡реЗрд╢рди рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ рддреЛ рдирд┐рдпрдВрддреНрд░рдг рдЙрд╕ рдкрд░ рдорд┐рд▓реЗрдЧрд╛ред
рдЬреЗрд▓реА
рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдкрдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдЖрдк рдЕрднреА рднреА рдкреНрд░рдпрд╛рд╕ / рдХреИрдЪ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдПрд░рд░рдПрдХреНрд╢рди рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ, рдпрджрд┐ рдЖрдкрдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдиреЗ рдФрд░ рдПрд░рд░рдПрдХреНрд╢рди рдореЗрдВ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреИрдЪ рд╕реЗ RuntimeException () рдХреЛ рдлреЗрдВрдХрдирд╛ рдЪрд╛рд╣рд┐рдПред (рдЖрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХрд╣рд╛ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЖрд╡рд╢реНрдпрдХ рд╣реИ)ред

рд╕рдВрдХреНрд░рдордгреЛрдВ рдореЗрдВ "рд▓рдЯрдХреА" рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдЙрдиреНрд╣реЗрдВ рд░рд╛рдЬреНрдп рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рд╡рд┐рдзрд┐ рдореЗрдВ "рдлрд╛рдВрд╕реА" рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд░реВрдк рдореЗрдВ:
  @Override public void configure(final StateMachineStateConfigurer<PurchaseState, PurchaseEvent> states) throws Exception { states .withStates() .initial(NEW) .end(PURCHASE_COMPLETE) .stateEntry() .stateExit() .state() .states(EnumSet.allOf(PurchaseState.class)); } 

рдпрд╣ рд╕рдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреИрд╕реЗ рдЪрд▓рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдЬреЗрд▓реА
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рд░рд╛рдЬреНрдп рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╕рдордп рдХрд╛рд░реНрд░рд╡рд╛рдИ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ (), рдЬреИрд╕реЗ
  states .withStates() .initial(NEW) .end(PURCHASE_COMPLETE) .state(randomAction()) 

рдЗрд╕реЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдХрд╣рддреЗ рд╣реИрдВ .stateEntry (), рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд╕реАрдзреЗ рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдХрд╣рддреЗ рд╣реИрдВ .state () рддреЛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд▓рдХреНрд╖реНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ рдЬрдмред
рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╣рдордиреЗ рд╕рднреА рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╕рдВрдХреНрд░рдордг рд╡рд┐рдиреНрдпрд╛рд╕ рдкрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХрдИ рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
 @Configuration @EnableStateMachineFactory public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<PurchaseState, PurchaseEvent> { @Override public void configure(final StateMachineConfigurationConfigurer<PurchaseState, PurchaseEvent> config) throws Exception { config .withConfiguration() .autoStartup(true) .listener(new PurchaseStateMachineApplicationListener()); } @Override public void configure(final StateMachineStateConfigurer<PurchaseState, PurchaseEvent> states) throws Exception { states .withStates() .initial(NEW) .end(PURCHASE_COMPLETE) .stateEntry() .stateExit() .state() .states(EnumSet.allOf(PurchaseState.class)); } @Override public void configure(final StateMachineTransitionConfigurer<PurchaseState, PurchaseEvent> transitions) throws Exception { transitions .withExternal() .source(NEW) .target(RESERVED) .event(RESERVE) .action(reservedAction(), errorAction()) .and() .withExternal() .source(RESERVED) .target(CANCEL_RESERVED) .event(RESERVE_DECLINE) .action(cancelAction(), errorAction()) .and() .withExternal() .source(RESERVED) .target(PURCHASE_COMPLETE) .event(BUY) .guard(hideGuard()) .action(buyAction(), errorAction()); } @Bean public Action<PurchaseState, PurchaseEvent> reservedAction() { return new ReservedAction(); } @Bean public Action<PurchaseState, PurchaseEvent> cancelAction() { return new CancelAction(); } @Bean public Action<PurchaseState, PurchaseEvent> buyAction() { return new BuyAction(); } @Bean public Action<PurchaseState, PurchaseEvent> errorAction() { return new ErrorAction(); } @Bean public Guard<PurchaseState, PurchaseEvent> hideGuard() { return new HideGuard(); } @Bean public StateMachinePersister<PurchaseState, PurchaseEvent, String> persister() { return new DefaultStateMachinePersister<>(new PurchaseStateMachinePersister()); } 

рдорд╢реАрди рдХреА рдпреЛрдЬрдирд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдпрд╣ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╣рдордиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдПрдиреНрдХреЛрдб рдХрд┐рдпрд╛ рд╣реИ (рдХреМрди рд╕реЗ рд╕рдВрдХреНрд░рдордг рдХрд┐рди рдШрдЯрдирд╛рдУрдВ рдкрд░ рдорд╛рдиреНрдп рд╣реИрдВ, рдХреМрди рд╕рд╛ рдЧрд╛рд░реНрдб рд╕реНрдерд┐рддрд┐ рдХреА рд░рдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреНрдпрд╛ рд╕реНрдерд┐рддрд┐ рд╣реЛрдиреЗ рдкрд░ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреМрди рд╕реА рдХрд╛рд░реНрд░рд╡рд╛рдИ)ред

рдирд┐рдпрдВрддреНрд░рдХ рдмрдирд╛рддреЗ рд╣реИрдВ:
 @RestController @SuppressWarnings("unused") public class PurchaseController { private final PurchaseService purchaseService; public PurchaseController(PurchaseService purchaseService) { this.purchaseService = purchaseService; } @RequestMapping(path = "/reserve") public boolean reserve(final String userId, final String productId) { return purchaseService.reserved(userId, productId); } @RequestMapping(path = "/cancel") public boolean cancelReserve(final String userId) { return purchaseService.cancelReserve(userId); } @RequestMapping(path = "/buy") public boolean buyReserve(final String userId) { return purchaseService.buy(userId); } } 


рд╕реЗрд╡рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕
 public interface PurchaseService { /** *    ,          * * @param userId id ,    ,      id  *    http- * @param productId id ,     * @return /  ,             *      . */ boolean reserved(String userId, String productId); /** *   /    * * @param userId id ,    ,      id  *    http- * @return /  ,             *      . */ boolean cancelReserve(String userId); /** *     * * @param userId id ,    ,      id  *    http- * @return /  ,             *      . */ boolean buy(String userId); } 

рдЬреЗрд▓реА
рдХреНрдпрд╛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмреАрди рдмрдирд╛рдирд╛ рдХреНрдпреЛрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ? рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рд╣рд╛рдБ, рд╣рд╛рдБ, рдФрд░ рдЬреЗрдиреНрдпрд╛ рдмреЛрд░рд┐рд╕реЛрд╡ рдиреЗ рд░рд┐рдкрд░ рдореЗрдВ рдмрддрд╛рдпрд╛), рдЬрдм рдПрдХ рдмрд╛рд░ рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдХ рдХрд╛рдордЪрд▓рд╛рдК рдЧреИрд░-рдЦрд╛рд▓реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рд╕реНрдкреНрд░рд┐рдВрдЧ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЙрдХреНрд╕реА рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдШрдЯрдХ рдХрд┐рд╕реА рднреА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ CGLIB рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЬреИрд╕реЗ рд╣реА рдЖрдк рдХреБрдЫ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ - рд╕реНрдкреНрд░рд┐рдВрдЧ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдкреНрд░реЙрдХреНрд╕реА рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдЧрд╛, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЖрдкрдХреЛ рдПрдХ рдЕрддреБрд▓рдиреАрдп рд╡рд╕реНрддреБ рдкреНрд░рдХрд╛рд░ рдорд┐рд▓реЗрдЧрд╛ рдФрд░ NoSuchBeanDefinitionExceptionред ред

рдЕрдЧрд▓рд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдЕрдкрдиреА рдорд╢реАрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╕реЗ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдмреАрди рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬреЛ рдорд╢реАрди рдХреА рдкрд┐рдЫрд▓реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред
рдЗрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реНрдЯреЗрдЯрдорд╛рдЗрди рдореЗрдВ рдПрдХ рдкрд░реНрд╕рд┐рд╕реНрдЯреЗрдВрд╕ рддрдВрддреНрд░ рд╣реИ:
 public class PurchaseStateMachinePersister implements StateMachinePersist<PurchaseState, PurchaseEvent, String> { private final HashMap<String, StateMachineContext<PurchaseState, PurchaseEvent>> contexts = new HashMap<>(); @Override public void write(final StateMachineContext<PurchaseState, PurchaseEvent> context, String contextObj) { contexts.put(contextObj, context); } @Override public StateMachineContext<PurchaseState, PurchaseEvent> read(final String contextObj) { return contexts.get(contextObj); } } 

рд╣рдорд╛рд░реЗ рдЕрдиреБрднрд╡рд╣реАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рд╛рдЬреНрдп рдХреЗ рд╕реНрдЯреЛрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЧреИрд░-рднреЛрд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдпрд╣ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реЛрдЧрд╛, рддреАрд╕рд░реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдпрд╣ рд╡рд╣ рдХреБрдВрдЬреА рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдЖрдкрдХреА рдорд╢реАрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рднреА рд╕реНрдЯреЗрдЯрд╕, рдЪрд░ рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВрдиреЗ рд╕реЗрд╡ рдЖрдИрдбреА рдХреЗ рд▓рд┐рдП рдпреВрдЬрд░ рдЖрдИрдбреА рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛, рдЬреЛ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХреБрдВрдЬреА рд╣реЛ рд╕рдХрддреА рд╣реИ (рдпреВрдЬрд░ рд╕реЗрд╢рди_рдб, рдпреВрдирд┐рдХ рд▓реЙрдЧрд┐рди рдЗрддреНрдпрд╛рджрд┐)ред
рдЬреЗрд▓реА
рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рдмреЙрдХреНрд╕ рд╕реЗ рд░рд╛рдЬреНрдпреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рддрдВрддреНрд░ рд╣рдореЗрдВ рд╕реВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдорд╢реАрди рдХреА рд╕реНрдерд┐рддрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдереА рдФрд░ рдПрдХ рдиреМрдХрд░реА рджреНрд╡рд╛рд░рд╛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ рдЬреЛ рдорд╢реАрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдерд╛ред
рдореБрдЭреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╕реНрдерд┐рддрд┐ рдкрд░ рдЙрдкрд╡рд╛рд╕ рдХрд░рдирд╛ рдерд╛, рдХреБрдЫ InitAction рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдорд╢реАрди рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░, рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЬрдмрд░рди рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдШрдЯрдирд╛, рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рдЬреЛ рдКрдкрд░ рдХрд░рддрд╛ рд╣реИ:
 stateMachine .getStateMachineAccessor() .doWithAllRegions(access -> { access.resetStateMachine(new DefaultStateMachineContext<>({ResetState}, null, null, null, null)); }); stateMachine.start(); stateMachine.sendEvent({NewEventFromResetState}); 


рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реЗрд╡рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ:
  @Override public boolean reserved(final String userId, final String productId) { final StateMachine<PurchaseState, PurchaseEvent> stateMachine = stateMachineFactory.getStateMachine(); stateMachine.getExtendedState().getVariables().put("PRODUCT_ID", productId); stateMachine.sendEvent(RESERVE); try { persister.persist(stateMachine, userId); } catch (final Exception e) { e.printStackTrace(); return false; } return true; } 

рд╣рдо рдХрд╛рд░рдЦрд╛рдиреЗ рд╕реЗ рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдорд╢реАрди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдПрдХ productId рд╣реИ, рд╕рдВрджрд░реНрдн рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдмреЙрдХреНрд╕ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдЕрдкрдиреА рдЬрд░реВрд░рдд рдХреА рд╣рд░ рдЪреАрдЬ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рднреА рд╕реНрдЯреЗрдЯрдорд╛рдЗрди рдмреАрди рдпрд╛ рдЗрд╕рдХреЗ рд╕рдВрджрд░реНрдн рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдорд╢реАрди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рддрдм рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рдЬрдм рд╕рдВрджрд░реНрдн рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред , рддреЛ рд╢реБрд░реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реА рдХрд╛рд░ рдирдИ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реЛрдЧреА, рдШрдЯрдирд╛ рдХреЛ рдорд╛рд▓ рдХреЗ рдЖрд░рдХреНрд╖рдг рдкрд░ рдлреЗрдВрдХ рджреЗрдВрдЧреЗред

рд╢реЗрд╖ рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╕рдорд╛рди рд╣реИрдВ:
  @Override public boolean cancelReserve(final String userId) { final StateMachine<PurchaseState, PurchaseEvent> stateMachine = stateMachineFactory.getStateMachine(); try { persister.restore(stateMachine, userId); stateMachine.sendEvent(RESERVE_DECLINE); } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override public boolean buy(final String userId) { final StateMachine<PurchaseState, PurchaseEvent> stateMachine = stateMachineFactory.getStateMachine(); try { persister.restore(stateMachine, userId); stateMachine.sendEvent(BUY); } catch (Exception e) { e.printStackTrace(); return false; } return true; } 

рдпрд╣рд╛рдВ рд╣рдо рдкрд╣рд▓реЗ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдИрдбреА рдХреЗ рд▓рд┐рдП рдорд╢реАрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдПрдХ рдРрд╕реА рдШрдЯрдирд╛ рдХреЛ рдлреЗрдВрдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдкреАрдЖрдИ рд╡рд┐рдзрд┐ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ productId рдЕрдм рд╡рд┐рдзрд┐ рдореЗрдВ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ, рд╣рдордиреЗ рдЗрд╕реЗ рдорд╢реАрди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЗрд╕рдХреЗ рдмреИрдХрдЕрдк рд╕реЗ рдорд╢реАрди рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред
рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╣рдо рдорд╢реАрди рдЖрдИрдбреА рд╕реЗ рдЙрддреНрдкрд╛рдж рдЖрдИрдбреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рд▓реЙрдЧ рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХреЛрдб рджреЗ рджреВрдВрдЧрд╛ред
 public class ReservedAction implements Action<PurchaseState, PurchaseEvent> { @Override public void execute(StateContext<PurchaseState, PurchaseEvent> context) { final String productId = context.getExtendedState().get("PRODUCT_ID", String.class); System.out.println("   " + productId + " ."); } } 

рд╣рдо рд╢реНрд░реЛрддрд╛ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдХреБрдЫ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдкрдиреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВ:
 public class PurchaseStateMachineApplicationListener implements StateMachineListener<PurchaseState, PurchaseEvent> { @Override public void stateChanged(State<PurchaseState, PurchaseEvent> from, State<PurchaseState, PurchaseEvent> to) { if (from.getId() != null) { System.out.println("   " + from.getId() + "   " + to.getId()); } } @Override public void stateEntered(State<PurchaseState, PurchaseEvent> state) { } @Override public void stateExited(State<PurchaseState, PurchaseEvent> state) { } @Override public void eventNotAccepted(Message<PurchaseEvent> event) { System.out.println("   " + event); } @Override public void transition(Transition<PurchaseState, PurchaseEvent> transition) { } @Override public void transitionStarted(Transition<PurchaseState, PurchaseEvent> transition) { } @Override public void transitionEnded(Transition<PurchaseState, PurchaseEvent> transition) { } @Override public void stateMachineStarted(StateMachine<PurchaseState, PurchaseEvent> stateMachine) { System.out.println("Machine started"); } @Override public void stateMachineStopped(StateMachine<PurchaseState, PurchaseEvent> stateMachine) { } @Override public void stateMachineError(StateMachine<PurchaseState, PurchaseEvent> stateMachine, Exception exception) { } @Override public void extendedStateChanged(Object key, Object value) { } @Override public void stateContext(StateContext<PurchaseState, PurchaseEvent> stateContext) { } } 

рдПрдХрдорд╛рддреНрд░ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЗрди рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдЖрдкрдХреЛ рдЗрди рд╕рднреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЦрд╛рд▓реА рд╣реИрдВрдЧ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ, рдЬреЛ рдХрд╡рд░реЗрдЬ рдХрд╣реЗрдЧрд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░рд╛ рддрд░реАрдХреЛрдВ рдХреЛ рдХрд╡рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдпрд╣рд╛рдВ рд▓рд┐рд╕рдирд░ рдореЗрдВ рд╣рдо рдорд╢реАрди рдХреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдШрдЯрдирд╛рдУрдВ рдкрд░ рдмрд┐рд▓реНрдХреБрд▓ рдХрд┐рд╕реА рднреА рдореАрдЯреНрд░рд┐рдХ рдХреЛ рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рднреБрдЧрддрд╛рди рдирд╣реАрдВ рдЧреБрдЬрд░рддреЗ рд╣реИрдВ, рдорд╢реАрди рдЕрдХреНрд╕рд░ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА PAYMENT_FAIL рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЪрд▓реА рдЬрд╛рддреА рд╣реИ, рд╣рдо рдмрджрд▓рд╛рд╡ рд╕реБрдирддреЗ рд╣реИрдВ, рдФрд░ рдЕрдЧрд░ рдорд╢реАрди рдПрдХ рдЧрд▓рдд рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЪрд▓реА рдЧрдИ - рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдПрдХ рд╡рд┐рд╖рдо рд▓реЙрдЧ рдореЗрдВред рдпрд╛ рдЖрдзрд╛рд░ рдпрд╛ рдкреБрд▓рд┐рд╕ рдХреЛ рдмреБрд▓рд╛рдУ, рдЬреЛ рднреА рд╣реЛ)ред
рдЬреЗрд▓реА
рд▓рд┐рд╕рдирд░-рдИ рдореЗрдВ рдПрдХ рдИрд╡реЗрдВрдЯ рд╕реНрдЯреЗрдЯрдореИрдЪрд┐рдирд┐рдпрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЕрддрд┐ рд╕реВрдХреНрд╖реНрдо рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде, рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЖрдк рдЗрд╕реЗ рдХреИрдЪ рдореЗрдВ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдорд╢реАрди рдпрд╣ рдирд╣реАрдВ рдорд╛рдирддреА рд╣реИ рдХрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдереА, рдЖрдкрдХреЛ рдХреИрдЪ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмреЛрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
StateMachine.setStateMachineError (рдЕрдкрд╡рд╛рдж) рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдкрд╛рд╕ рдХрд░реЗрдВред

рд╣рдордиреЗ рдЬреЛ рдХрд┐рдпрд╛ рд╣реИ рдЙрд╕рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рджреЛ рдорд╛рдорд▓реЛрдВ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдХрд░реЗрдВрдЧреЗ:
  • 1. рдЖрд░рдХреНрд╖рдг рдФрд░ рдЦрд░реАрдж рдХреА рдмрд╛рдж рдХреА рдЕрд╕реНрд╡реАрдХреГрддрд┐ред рд╣рдо рдЖрд╡реЗрджрди рдХреЛ рдпреВрдЖрд░рдЖрдИ "/ рд░рд┐рдЬрд░реНрд╡" рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ userId = 007, productId = 10001, рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдж рдкреИрд░рд╛рдореАрдЯрд░ userId = 007 рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз "рд░рджреНрдж" рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдХрдВрд╕реЛрд▓ рдЖрдЙрдЯрдкреБрдЯ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛:
    Machine started
    10001 .
    NEW RESERVED
    Machine started
    10001
    RESERVED CANCEL_RESERVED
  • 2. рдЖрд░рдХреНрд╖рдг рдФрд░ рд╕рдлрд▓ рдЦрд░реАрдж:
    Machine started
    10001 .
    NEW RESERVED
    Machine started
    10001
    RESERVED PURCHASE_COMPLETE

рдирд┐рд╖реНрдХрд░реНрд╖


рдЕрдВрдд рдореЗрдВ, рдореИрдВ рд░реВрдкрд░реЗрдЦрд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдХреЛрдб рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдкрд░реАрдХреНрд╖рдг рдорд╢реАрди рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЖрдк рд╡рд┐рдиреНрдпрд╛рд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  @Test public void testWhenReservedCancel() throws Exception { StateMachine<PurchaseState, PurchaseEvent> machine = factory.getStateMachine(); StateMachineTestPlan<PurchaseState, PurchaseEvent> plan = StateMachineTestPlanBuilder.<PurchaseState, PurchaseEvent>builder() .defaultAwaitTime(2) .stateMachine(machine) .step() .expectStates(NEW) .expectStateChanged(0) .and() .step() .sendEvent(RESERVE) .expectState(RESERVED) .expectStateChanged(1) .and() .step() .sendEvent(RESERVE_DECLINE) .expectState(CANCEL_RESERVED) .expectStateChanged(1) .and() .build(); plan.test(); } @Test public void testWhenPurchaseComplete() throws Exception { StateMachine<PurchaseState, PurchaseEvent> machine = factory.getStateMachine(); StateMachineTestPlan<PurchaseState, PurchaseEvent> plan = StateMachineTestPlanBuilder.<PurchaseState, PurchaseEvent>builder() .defaultAwaitTime(2) .stateMachine(machine) .step() .expectStates(NEW) .expectStateChanged(0) .and() .step() .sendEvent(RESERVE) .expectState(RESERVED) .expectStateChanged(1) .and() .step() .sendEvent(BUY) .expectState(PURCHASE_COMPLETE) .expectStateChanged(1) .and() .build(); plan.test(); } 

рдЬреЗрд▓реА
рдпрджрд┐ рдЖрдк рдЕрдЪрд╛рдирдХ рд╕рд╛рдорд╛рдиреНрдп рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрджрд░реНрдн рдХреЗ рдмрд┐рдирд╛ рдЕрдкрдиреА рдорд╢реАрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдмрд┐рд▓реНрдбрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдорд╢реАрди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИ), рдПрдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдФрд░ рдЧрд╛рд░реНрдб рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рдпрд╣ рдмрд┐рдирд╛ рд╕рдВрджрд░реНрдн рдХреЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЖрдк рдереЛрдбрд╝рд╛ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рд░реВрдкрд░реЗрдЦрд╛ рдордЬрд╝рд╛рдХ рдкрд░ рд╣реИ, рдпрд╣ рдПрдХ рдкреНрд▓рд╕ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рдорд▓реЛрдВ рдкрд░ рдХреМрди рд╕реЗ рдХрд╛рд░реНрдп рдХрд╣реЗ рдЧрдП, рдХреМрди рд╕реЗ рдирд╣реАрдВ, рдХрд┐рддрдиреА рдмрд╛рд░ рдХрд┐рдП рдЧрдП рдЖрджрд┐ред

рдкреБрдирд╢реНрдЪ


, , , , (Guard- Action- )


, choice, , switch, Guards, , choice Guard, Events, , , .

рд╕рдВрджрд░реНрдн



Source: https://habr.com/ru/post/hi462371/


All Articles