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@postconstructannotation,@postconstructcalled 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 casemyapplistenerimplementonapplicationeventmethod receivescontextrefreshedevent
spring boot approach
the runners: there 2 useful interfaces
commandlinerunner,applicationrunnerboth 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 implementsapplicationlistenerusingapplicationreadyeventgeneric.
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