通过指定接口,重写指定方法,可以在Bean对应的生命周期方法中执行相应的程序
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.wu</groupId> <artifactId>smartport</artifactId> <version>0.0.1-SNAPSHOT</version> <name>smartport</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
2.1 Order = 1
package com.wu.smartport.controller; import com.wu.smartport.test.User; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Order(1) public class TestController implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, BeanDefinitionRegistryPostProcessor, InitializingBean, DisposableBean { @Autowired private User user; /** * 最先执行,需要接口BeanNameAware * * @param name */ @Override public void setBeanName(String name) { // 获取到的是testController,即注入进Spring中的名称 System.out.println("setBeanName:" + name); } /** * 第2个执行,需要接口BeanFactoryAware * beanFactory可以获取其他已注入的Bean对象,但无法注入其他对象 * * @param beanFactory * @throws BeansException */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { } /** * 第3个执行,需要ApplicationContextAware接口 * 可以获取到上下文对象applicationContext,允许容器通过应用程序上下文环境创建、获取、管理bean * * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 可以通过上下文对象获取工厂并注入对象 AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); } /** * 第4个执行,依赖于InitializingBean接口 * * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { } /** * 第5个执行,依赖于BeanDefinitionRegistryPostProcessor接口 * 当完成本方法后,对象就会完成注入 * @param registry * @throws BeansException */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { } /** * 第6个执行,来源于BeanFactoryPostProcessor接口,该接口被BeanDefinitionRegistryPostProcessor接口实现了。 * 一般的Bean对象在此方法前都被注入到了容器中,如果本对象没有获取到,则可以在这里获取。 * @param beanFactory * @throws BeansException */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Object user = beanFactory.getBean("user"); } /** * 第7个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象的时候,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 第8个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象之后,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 在本对象被销毁后执行,依赖于DisposableBean接口 * @throws Exception */ @Override public void destroy() throws Exception { } }
2.2 Order = 15
package com.wu.smartport.test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; /** * @Author :吴用 * @Date :2021-01-05 8:40 * @Version :1.0 */ @Service @Order(15) public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, BeanDefinitionRegistryPostProcessor, InitializingBean, DisposableBean { @Value("张三") private String name; @Value("12") private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } /** * 最先执行,需要接口BeanNameAware * * @param name */ @Override public void setBeanName(String name) { System.out.println("setBeanName:" + name); } /** * 第2个执行,需要接口BeanFactoryAware * beanFactory可以获取其他已注入的Bean对象,但无法注入其他对象 * * @param beanFactory * @throws BeansException */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { } /** * 第3个执行,需要ApplicationContextAware接口 * 可以获取到上下文对象applicationContext,允许容器通过应用程序上下文环境创建、获取、管理bean * * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { } /** * 第4个执行,依赖于InitializingBean接口 * * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { } /** * 第5个执行,依赖于BeanDefinitionRegistryPostProcessor接口 * 当完成本方法后,对象就会完成注入 * @param registry * @throws BeansException */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { } /** * 第6个执行,来源于BeanFactoryPostProcessor接口,该接口被BeanDefinitionRegistryPostProcessor接口实现了。 * 一般的Bean对象在此方法前都被注入到了容器中,如果本对象没有获取到,则可以在这里获取。 * @param beanFactory * @throws BeansException */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Object user = beanFactory.getBean("user"); } /** * 第7个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象的时候,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 第8个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象之后,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 在本对象被销毁后执行,依赖于DisposableBean接口 * @throws Exception */ @Override public void destroy() throws Exception { } }
2.3 Order = 30
package com.wu.smartport.test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * @Author :吴用 * @Date :2021-01-05 9:48 * @Version :1.0 */ @Order(30) @Component public class User2 implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, BeanDefinitionRegistryPostProcessor, InitializingBean, DisposableBean { @Value("张三") private String name; @Value("12") private int age; public User2() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } /** * 最先执行,需要接口BeanNameAware * * @param name */ @Override public void setBeanName(String name) { System.out.println("setBeanName:" + name); } /** * 第2个执行,需要接口BeanFactoryAware * beanFactory可以获取其他已注入的Bean对象,但无法注入其他对象 * * @param beanFactory * @throws BeansException */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { } /** * 第3个执行,需要ApplicationContextAware接口 * 可以获取到上下文对象applicationContext,允许容器通过应用程序上下文环境创建、获取、管理bean * * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { } /** * 第4个执行,依赖于InitializingBean接口 * * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { } /** * 第5个执行,依赖于BeanDefinitionRegistryPostProcessor接口 * 当完成本方法后,对象就会完成注入 * @param registry * @throws BeansException */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { } /** * 第6个执行,来源于BeanFactoryPostProcessor接口,该接口被BeanDefinitionRegistryPostProcessor接口实现了。 * 一般的Bean对象在此方法前都被注入到了容器中,如果本对象没有获取到,则可以在这里获取。 * @param beanFactory * @throws BeansException */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Object user = beanFactory.getBean("user"); } /** * 第7个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象的时候,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 第8个执行,本方法将被多次执行,依赖于BeanPostProcessor接口 * 每注入一个对象之后,都会调用该方法 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return null; } /** * 在本对象被销毁后执行,依赖于DisposableBean接口 * @throws Exception */ @Override public void destroy() throws Exception { } }
2.4 实验结果
销毁的顺序
4.1 一般初始化
package com.wu.smartport.controller; /** * 观察者,用于初始化 * @Author :吴用 * @Date :2021-01-05 11:02 * @Version :1.0 */ public interface ObserverForInit { /** * 观察者初始化 */ void observerInit(); }
再让需要初始化操作的bean对象实现该接口
package com.wu.smartport.test; import com.wu.smartport.controller.ObserverForInit; import org.springframework.stereotype.Component; /** * @Author :吴用 * @Date :2021-01-05 11:11 * @Version :1.0 */ @Component public class User implements ObserverForInit { @Override public void observerInit() { System.out.println("我要进行初始化了!"); } }
然后再写一个管理bean初始化的类 通过遍历所有的Bean对象,然后查询指定的接口或者自定义注解,执行相应的操作(比如初始化操作。)
package com.wu.smartport.manager; import com.wu.smartport.controller.ObserverForInit; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; import java.util.Iterator; /** * @Author :吴用 * @Date :2021-01-05 11:06 * @Version :1.0 */ @Component public class ControllerInitManager implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Iterator<String> its = beanFactory.getBeanNamesIterator(); while (its.hasNext()) { String beanName = its.next(); try { Object bean = beanFactory.getBean(beanName); analysisObject(bean); } catch (BeanCreationException e) { } catch (Exception e) { e.printStackTrace(); } } } /** * 分析bean对象 * * @param bean */ private void analysisObject(Object bean) { analysisInterface(bean); analysisAnnotation(bean); } /** * 分析接口 * * @param bean */ private void analysisInterface(Object bean) { Class<?> beanClass = bean.getClass(); // 分析Interface 和 Annotation Class<?>[] interfaces = beanClass.getInterfaces(); // 分析Class for (Class infs : interfaces) { if (infs.equals(ObserverForInit.class)) { ((ObserverForInit) bean).observerInit(); } } } /** * 分析注解 * * @param bean */ private void analysisAnnotation(Object bean) { } }
4.2 按序初始化
package com.wu.smartport.controller; /** * 观察者,用于初始化 * @Author :吴用 * @Date :2021-01-05 11:02 * @Version :1.0 */ public interface ObserverForInit { /** * 观察者初始化 */ void observerInit(); /** * 初始化的顺序,数越小,优先级越高 * @return */ int getInitOrder(); }
bean对象
/** * @Author :吴用 * @Date :2021-01-04 22:51 * @Version :1.0 */ @Component public class PageManager implements ObserverForInit { @Override public void observerInit() { System.out.println("PageManager初始化"); } @Override public int getInitOrder() { return 1000; } }
管理初始化的类
package com.wu.smartport.manager; import com.wu.smartport.controller.ObserverForInit; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; /** * @Author :吴用 * @Date :2021-01-05 11:06 * @Version :1.0 */ @Component public class ControllerInitManager implements BeanFactoryPostProcessor { private TreeSet<ObserverForInit> inits = new TreeSet<>(Comparator.comparingInt(ObserverForInit::getInitOrder)); @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Iterator<String> its = beanFactory.getBeanNamesIterator(); while (its.hasNext()) { String beanName = its.next(); try { Object bean = beanFactory.getBean(beanName); analysisObject(bean); } catch (BeanCreationException e) { } catch (Exception e) { e.printStackTrace(); } } // 遍历完成后的操作 analysisByAfterIterator(); } /** * 分析bean对象 * * @param bean */ private void analysisObject(Object bean) { analysisInterface(bean); analysisAnnotation(bean); } /** * 遍历之后的操作 */ private void analysisByAfterIterator() { // 按照指定的顺序遍历 // 升序遍历,order小的先执行初始化方法 for (ObserverForInit o : inits) { o.observerInit(); } } /** * 分析接口 * * @param bean */ private void analysisInterface(Object bean) { Class<?> beanClass = bean.getClass(); // 分析Interface 和 Annotation Class<?>[] interfaces = beanClass.getInterfaces(); // 分析Class for (Class infs : interfaces) { if (infs.equals(ObserverForInit.class)) { inits.add((ObserverForInit) bean); } } } /** * 分析注解 * * @param bean */ private void analysisAnnotation(Object bean) { } }
5 基于 Springboot 实现冯诺依曼结构
package com.wu.smartport.test; import com.wu.smartport.SmartportApplication; import javafx.stage.Stage; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import java.io.IOException; import java.util.ArrayList; import java.util.function.Function; import static com.wu.smartport.config.BeanInitOrder.INIT_METHODS; import static com.wu.smartport.config.BeanInitOrder.STAGE_BEAN; /** * @Author :吴用 * @Date :2021-01-05 19:27 * @Version :1.0 */ public class Manager implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 执行方法告诉javaFx ArrayList<Function> arr; try{ // 尝试从容器中获取代码块 Object bean = beanFactory.getBean("function"); arr = (ArrayList<Function>)bean; }catch (Exception e2){ // 如果不存在则创建代码块 arr = new ArrayList<>(); } // 书写一段代码 Function<Void,Void> f = aVoid -> { // 相关的业务 return null; }; arr.add(f); // 将代码块注入到spring容器中 DefaultListableBeanFactory factory = (DefaultListableBeanFactory)beanFactory; factory.registerSingleton(INIT_METHODS,arr); } }
在之后一定会运行到的代码,比如启动类之后,可以执行指定的代码段。
package com.wu.smartport; import javafx.application.Application; import javafx.stage.Stage; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import java.util.ArrayList; import java.util.function.Function; import static com.wu.smartport.config.BeanInitOrder.INIT_METHODS; import static com.wu.smartport.config.BeanInitOrder.STAGE_BEAN; /** * 主启动类 * @author Wu_Sir */ @SpringBootApplication public class SmartportApplication{ private static volatile ConfigurableApplicationContext run; /** * 主程序入口 * * @param args */ public static void main(String[] args) { run = SpringApplication.run(SmartportApplication.class, args); // 查看是否有要处理的方法 try{ Object bean = beanFactory.getBean("function"); ArrayList<Function> arr = (ArrayList<Function>) bean; for (int i = 0; i < arr.size(); i++) { //如果有,则执行该方法。 Function f = arr.get(i); f.apply(null); } }catch (Exception e){ e.printStackTrace(); } } }
到此这篇关于springboot2.x解决运行顺序及Bean对象注入顺序的问题的文章就介绍到这了,更多相关springboot注入Bean顺序内容请搜索呐喊教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持呐喊教程!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。