Spring加载后初始化的9种方式 | 您所在的位置:网站首页 › spring注解中动态传值 › Spring加载后初始化的9种方式 |
本文来聊一下在spring中,当spring 容器启动后,我们有几种初始化操作的方式。 目录 Spring加载后初始化的几种方式 @Component和@Service加构造方法 ContextRefreshedEvent事件 代码如下: 输出结果: PostConstruct 注解 代码如下: 输出结果: InitializingBean 代码如下: 输出结果: init-method方法 代码如下: 输出结果: 实现 SmartInitializingSingleton 接口 代码如下: 输出结果: 重写 onRefresh()方法 CommandLineRunner(仅限Spring Boot) 代码如下: 输出结果: SpringApplicationRunListener(仅限Spring boot) 代码如下: 输出结果: 总结: Spring加载后初始化的几种方式@component和@service 加构造方法 ContextRefreshedEvent事件 PostConstruct 注解 InitializingBean init-method方法 实现 SmartInitializingSingleton 接口 重写 onRefresh()方法 CommandLineRunner(仅限Spring Boot) SpringApplicationRunListener(仅限Spring boot) 在spring 容器中有一个 Persion对象名字叫张三,需要在spring容器启动后调用它的run方法。代码如下 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class PersonConfig { @Bean public Person person(){ Person person = new Person(); person.setName("张三"); person.setAge(18); return person; } } @Component和@Service加构造方法 import org.springframework.stereotype.Component; @Component //@Service public class PersonConfig { private Person person; public PersonConfig() { person = new Person(); person.setName("张三"); person.setAge(18); } } ContextRefreshedEvent事件ContextRefreshedEvent:是Spring容器初始化完成后调用的事件。 ContextRefreshedEvent的父类是ApplicationContextEvent,是一个事件。所以我们通过ApplicationListener来实现。 代码如下: import com.example.springbootdemo.bean.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class PersonAfterListener implements ApplicationListener { @Autowired private Person person; @Override public void onApplicationEvent(ContextRefreshedEvent event) { person.run("ContextRefreshedEvent"); } } 输出结果: PostConstruct 注解PostConstruct注解修饰的方式,是在spring容器启动时运行的。优先级大于ContextRefreshedEvent事件。 代码如下: import com.example.springbootdemo.bean.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component public class PersonAfterPostConstruct { @Autowired private Person person; @PostConstruct public void postConstruct(){ person.run("PostConstruct"); } } 输出结果:由此可见,PostConstruct优先级大于ContextRefreshedEvent事件。 InitializingBeanInitializingBean是spring容器在启动并初始化好内部示例后调用的,用来最终为总体bean添加最后属性和操作。 官方原话:This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set. 代码如下: import com.example.springbootdemo.bean.Person; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class PersonAfterInitializingBean implements InitializingBean { @Autowired private Person person; @Override public void afterPropertiesSet() throws Exception { person.run("InitializingBean"); } } 输出结果: init-method方法这种方法有一定的局限性,并且可能会覆盖曾经的init操作,需要慎用。 Bean在加载到Spring容器中时需要先将Bean的定义信息抽象为BeanDefinition,其中有一个属性init-method代表将来Bean初始化时要调用的方法。 我们通过BeanFactoryPostProcessor来注入init-method方法,并且该方法必须是没有参数的 。 代码如下: import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; @Component public class PersonAfterInit implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition person = beanFactory.getBeanDefinition("person"); person.setInitMethodName("run"); } } 输出结果: 实现 SmartInitializingSingleton 接口SmartInitializingSingleton是Bean容器在初始化所有非懒加载的单例Bean后调用的方法。 代码如下: import com.example.springbootdemo.bean.Person; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class PersonAfterSmartInitializingSingleton implements SmartInitializingSingleton { @Autowired private Person person; @Override public void afterSingletonsInstantiated() { person.run("SmartInitializingSingleton"); } } 输出结果: 重写 onRefresh()方法这个我实在是不会,但我不藏着掖着,告诉你也能实现。 CommandLineRunner(仅限Spring Boot)CommandLineRunner 是一个Spring boot 接口,在应用初始化后执行,且仅会执行一次。可以用来打印项目中配置文件的参数,方便排查问题。 代码如下: import com.example.springbootdemo.bean.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class PersonAfterCommandLineRunner implements CommandLineRunner { @Autowired private Person person; @Override public void run(String... args) throws Exception { person.run("CommandLineRunner"); } } 输出结果: SpringApplicationRunListener(仅限Spring boot)SpringBoot的生命周期事件监听方法,需要搭配resource/META-INF/spring.factories 文件使用。 代码如下:JAVA代码: import com.example.springbootdemo.bean.Person; import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplicationRunListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import java.time.Duration; public class PersonAfterSpringApplicationRunListener implements SpringApplicationRunListener { private final SpringApplication application; private final String[] args; public PersonAfterSpringApplicationRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; } @Override public void starting(ConfigurableBootstrapContext bootstrapContext) { /* * Person has not been registered */ // Person person = bootstrapContext.get(Person.class); // person.run("SpringApplicationRunListener:starting"); } @Override public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) { /* * Person has not been registered */ // Person person = bootstrapContext.get(Person.class); // person.run("SpringApplicationRunListener:environmentPrepared"); } @Override public void contextPrepared(ConfigurableApplicationContext context) { /* * Person has not been registered */ // Person person = context.getBean(Person.class); // person.run("SpringApplicationRunListener:contextPrepared"); } @Override public void contextLoaded(ConfigurableApplicationContext context) { /* * Person has not been registered */ // Person person = context.getBean(Person.class); // person.run("SpringApplicationRunListener:contextLoaded"); } @Override public void started(ConfigurableApplicationContext context, Duration timeTaken) { Person person = context.getBean(Person.class); person.run("SpringApplicationRunListener:started"); } @Override public void ready(ConfigurableApplicationContext context, Duration timeTaken) { Person person = context.getBean(Person.class); person.run("SpringApplicationRunListener:ready"); } @Override public void failed(ConfigurableApplicationContext context, Throwable exception) { Person person = context.getBean(Person.class); person.run("SpringApplicationRunListener:failed"); } } spring.factories org.springframework.boot.SpringApplicationRunListener=com.example.springbootdemo.impl.PersonAfterSpringApplicationRunListener 输出结果: 总结:执行优先级:init-Method >> InitializingBean >> PostConstruct >> SmartInitializingSingleton >> ContextRefreshedEvent >> SpringApplicationRunListener:started >> CommandLineRunner >> SpringApplicationRunListener:ready |
CopyRight 2018-2019 实验室设备网 版权所有 |