java - Best way to initialize beans in Spring context after application started? -
i need init beans in spring context after application has started, init beans in class annotation @configuration this:
@configuration public class appconfig { @inject @bean public beana init(param1, param2, etc...) { --- code construct bean --- } @inject @bean public beanb init(param1, param2, etc...) { --- code construct bean b --- } }
but beans need init after application startup approach create class listen applicationreadyevent event in spring , put code init beans in class.
@configuration class applicationstartinglistener implements applicationlistener<applicationreadyevent>{ ---- code init bean here ---- @override public void onapplicationevent(applicationreadyevent event) { --- if put init bean code in here, correct? ---- } }
does best way? or there other better approaching solutions?
thanks.
i enumerate other approaches in order init beans, grouped approach in standard approach , spring boot approach.
standard approach
@postconstruct
: annotation triggers method after bean create, doesn't allow input parameters.@bean(init-method="sominitmehotd")
: approach totally related spring bean lifecycle , called after bean creation, if using method@postconstruct
annotation,@postconstruct
called first. approach doesn't allow input parameters.applicationlistener
: interface allows listen standard events related context lifecycle, can listen customized events. example: create classmyapplistener
, implementsapplicationlistener<contextrefreshedevent>
in casemyapplistener
implementonapplicationevent
method receivescontextrefreshedevent
spring boot approach
the runners: there 2 useful interfaces
commandlinerunner
,applicationrunner
both of them run after applicationcontext created both of them allows inject beans input parameters.spring boot listeners: spring application gives additional events standards events comes application context. 1 of event
applicationreadyevent
, fire when application ready receive request. in order listen events implementsapplicationlistener
usingapplicationreadyevent
generic.
here example:
mybean class has different methods called each approach listed above, every method call print method , method has thread.sleep in order validate order every listener called.
import javax.annotation.postconstruct; public class mybean { private string myvar=""; public mybean(){ } @postconstruct public void postconstructinit(){ this.myvar="post init called"; print(); } public void beaninit(){ this.myvar="bean init called"; print(); } public void contextinit(){ this.myvar="context init called"; print(); } public void runnerinit(){ this.myvar="runner init called"; print(); } public void bootlistenerinit(){ this.myvar="boot init called"; print(); } public void print(){ system.out.println(this.myvar); try { thread.sleep(3000); } catch (interruptedexception e) { e.printstacktrace(); } } }
here contextrefreshlistener
class listen contextrefreshedevent
, handle it.
public class contextrefreshlistener implements applicationlistener<contextrefreshedevent> { @override public void onapplicationevent(contextrefreshedevent contextrefreshedevent) { contextrefreshedevent.getapplicationcontext().getbean(mybean.class).contextinit(); } }
and bootlistener
receive applicationreadyevent
comes spring application.
public class mybootlistener implements applicationlistener<applicationreadyevent> { @override public void onapplicationevent(applicationreadyevent applicationreadyevent) { applicationreadyevent.getapplicationcontext().getbean(mybean.class).bootlistenerinit(); } }
and spring boot application
@springbootapplication public class stackoverflowbootapplication { public static void main(string[] args) { springapplication.run(stackoverflowbootapplication.class, args); } @bean(name = "mybean", initmethod = "beaninit") public mybean getmybean(){ return new mybean(); } @bean public contextrefreshlistener getcontextrefreshedlistener(){return new contextrefreshlistener();} @bean public mybootlistener getbootlistener(){return new mybootlistener();} @bean public commandlinerunner getrunner(applicationcontext ctx){ return (args) -> { ctx.getbean(mybean.class).runnerinit(); }; } }
the output is:
post init called bean init called context init called runner init called boot init called
post init called
output comes
@postconstruct public void init(){ this.initbypostconstruct="post init called";
bean init called
comes initmethod
value
@bean(name = "mybean", initmethod = "beaninit") public mybean getmybean(){ return new mybean(); } }
context init called
comes contextrefreshedevent
public void onapplicationevent(contextrefreshedevent contextrefreshedevent) { contextrefreshedevent.getapplicationcontext().getbean(mybean.class).contextinit(); }
runner init called
comes commandlinerunner
@bean public commandlinerunner getrunner(applicationcontext ctx){ return (args) -> { ctx.getbean(mybean.class).runnerinit(); }; }
boot init called
comes applicationreadyevent
public void onapplicationevent(applicationreadyevent applicationreadyevent) { applicationreadyevent.getapplicationcontext().getbean(mybean.class).bootlistenerinit(); }
all listed scenarios triggered spring
, didi'nt call of events directly, of them called spring framework
.
Comments
Post a Comment