Spring容器载入bean顺序是不肯定的,Spring框架没有约定特定顺序逻辑规范。但Spring保证若是A依赖B(如beanA中有@Autowired B的变量),那么B将先于A被加载。spring
逻辑判断
在业务层本身控制A,B的初始化顺序框架
构造方法依赖
@Component publicclass DemoA { private String name = "demo A"; public DemoA(DemoB demoB) { System.out.println(name); } } @Component publicclass DemoB { private String name = "demo B"; public CDemoB() { System.out.println(name); } } 这个时候构造A的时候就会先去构造B
使用@DependsOn
Spring 中的@DependsOn能够保证被依赖的bean先于当前bean被容器建立ide
@DependsOn注解能够定义在类和方法上,意思是我这个组件要依赖于另外一个组件,也就是说被依赖的组件会比该组件先注册到IOC容器中。post
类上使用注解: package com.spring.master.spring; import org.springframework.stereotype.Component; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:55 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ @Component public class EventSource { public EventSource(){ System.out.println("事件源建立"); } } package com.spring.master.spring.dependson; import org.springframework.stereotype.Component; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:56 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ @Component public class EventListener { public EventListener(){ System.out.println("监听器建立"); } } package com.spring.master.spring.dependson; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:57 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ @Configuration @ComponentScan(basePackages = "com.spring.master.spring") public class SpringConfig { } 启动服务: 事件源建立 监听器建立 备注: Spring默认扫描包时会根据文件在文件夹的位置前后顺序扫描加载 ******************************************************************************************** 使用@DependsOn注解: package com.spring.master.spring; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:55 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ @Component @DependsOn(value = {"eventListener"}) public class EventSource { public EventSource(){ System.out.println("事件源建立"); } } 启动服务: 监听器建立 事件源建立
方法上使用注解: package com.spring.master.spring; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:55 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ //@Component //@DependsOn(value = {"eventListener"}) public class EventSource { public EventSource(){ System.out.println("事件源建立"); } } package com.spring.master.spring.dependson; import org.springframework.stereotype.Component; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:56 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ //@Component public class EventListener { public EventListener(){ System.out.println("监听器建立"); } } package com.spring.master.spring.dependson; import com.spring.master.spring.EventSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; /** * @author Huan Lee * @version 1.0 * @date 2020-09-22 15:57 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。 */ @Configuration @ComponentScan(basePackages = "com.spring.master.spring") public class SpringConfig { @Bean @DependsOn(value = {"eventListener"}) public EventSource eventSource(){ return new EventSource(); } @Bean public EventListener eventListener(){ return new EventListener(); } } 启动服务输出: 监听器建立 事件源建立
BeanFactoryPostProcessor
容器加载bean以前:BeanFactoryPostProcessor 能够容许咱们在容器加载任何bean以前修改应用上下文中的BeanDefinitionui
在本例中,就能够把A的初始化逻辑放在一个 BeanFactoryPostProcessor 中。 @Component public class ABeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { A.initA(); } } 这种方式把A中的初始化逻辑放到了加载bean以前,很适合加载系统全局配置,可是这种方式中初始化逻辑不能依赖bean的状态。
BeanPostProcessor
@Component publicclass HDemo1 { private String name = "h demo 1"; public HDemo1() { System.out.println(name); } } @Component publicclass HDemo2 { private String name = "h demo 2"; public HDemo2() { System.out.println(name); } }
@Component publicclass DemoBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) { if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { thrownew IllegalArgumentException( "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory); } this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } @Override @Nullable public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { // 在bean实例化以前作某些操做 if ("HDemo1".equals(beanName)) { HDemo2 demo2 = beanFactory.getBean(HDemo2.class); } return null; } }
请将目标集中在postProcessBeforeInstantiation
,这个方法在某个 bean 的实例化以前,会被调用,这就给了咱们控制 bean 加载顺序的机会。this