Bean后处理器

Bean后处理器作用

 
public class Bean1 { private static final Logger log = LoggerFactory.getLogger(Bean1.class); private Bean2 bean2; @Autowired public void setBean2(Bean2 bean2) { log.debug("@Autowired 生效: {}", bean2); this.bean2 = bean2; } @Autowired private Bean3 bean3; @Resource public void setBean3(Bean3 bean3) { log.debug("@Resource 生效: {}", bean3); this.bean3 = bean3; } private String home; @Autowired public void setHome(@Value("${JAVA_HOME}") String home) { log.debug("@Value 生效: {}", home); this.home = home; } @PostConstruct public void init() { log.debug("@PostConstruct 生效"); } @PreDestroy public void destroy() { log.debug("@PreDestroy 生效"); } @Override public String toString() { return "Bean1{" + "bean2=" + bean2 + ", bean3=" + bean3 + ", home='" + home + '\'' + '}'; } }
public class Bean2 { }
public class Bean3 { }
不加bean后处理器
/* bean 后处理器的作用 */ public class A04 { public static void main(String[] args) { // ⬇️GenericApplicationContext 是一个【干净】的容器 GenericApplicationContext context = new GenericApplicationContext(); // ⬇️用原始方法注册三个 bean context.registerBean("bean1", Bean1.class); context.registerBean("bean2", Bean2.class); context.registerBean("bean3", Bean3.class); // ⬇️初始化容器 context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例 System.out.println(context.getBean(Bean1.class)); // ⬇️销毁容器 context.close(); /* 学到了什么 a. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能 b. 这些扩展功能由 bean 后处理器来完成 */ } }
notion image

AutowiredAnnotationBeanPostProcessor

添加对 @Autowired @Value 的支持
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // @Autowired @Value //
notion image

原理解析

  1. AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata 用来获取某个 bean 上加了 @Value @Autowired 的成员变量,方法参数的信息,表示为 InjectionMetadata
  1. InjectionMetadata 可以完成依赖注入
  1. InjectionMetadata 内部根据成员变量,方法参数封装为 DependencyDescriptor 类型
  1. 有了 DependencyDescriptor,就可以利用 beanFactory.doResolveDependency 方法进行基于类型的查找
public class DigInAutowired { public static void main(String[] args) throws Throwable { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.registerSingleton("bean2", new Bean2()); // 创建过程,依赖注入,初始化 beanFactory.registerSingleton("bean3", new Bean3()); beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); // @Value beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders); // ${} 的解析器 // 1. 查找哪些属性、方法加了 @Autowired, 这称之为 InjectionMetadata AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor(); processor.setBeanFactory(beanFactory); Bean1 bean1 = new Bean1(); System.out.println(bean1); processor.postProcessProperties(null, bean1, "bean1"); // 执行依赖注入 @Autowired @Value System.out.println(bean1); } }
Bean1{bean2=null, bean3=null, home='null'} [DEBUG] 07:59:45.403 [main] com.onethink.a04.Bean1 - @Autowired 生效: com.onethink.a04.Bean2@515c6049 [DEBUG] 07:59:45.414 [main] com.onethink.a04.Bean1 - @Value 生效: D:\DevEvn\jdk\jdk-17.0.5 Bean1{bean2=com.onethink.a04.Bean2@515c6049, bean3=com.onethink.a04.Bean3@776aec5c, home='D:\DevEvn\jdk\jdk-17.0.5'}
postProcessProperties源码
notion image
使用反射调用findAutowiringMetadata 方法
public static void main(String[] args) throws Throwable { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.registerSingleton("bean2", new Bean2()); // 创建过程,依赖注入,初始化 beanFactory.registerSingleton("bean3", new Bean3()); beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); // @Value beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders); // ${} 的解析器 // 1. 查找哪些属性、方法加了 @Autowired, 这称之为 InjectionMetadata AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor(); processor.setBeanFactory(beanFactory); Bean1 bean1 = new Bean1(); Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class); findAutowiringMetadata.setAccessible(true); InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);// 获取 Bean1 上加了 @Value @Autowired 的成员变量,方法参数信息 System.out.println(metadata); }
meta包含了需要注入的元素
notion image
metadata.inject 进行依赖注入
Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class); findAutowiringMetadata.setAccessible(true); InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);// 获取 Bean1 上加了 @Value @Autowired 的成员变量,方法参数信息 System.out.println(metadata); System.out.println(bean1); // 2. 调用 InjectionMetadata 来进行依赖注入, 注入时按类型查找值 metadata.inject(bean1, "bean1", null); System.out.println(bean1);
按类型查找值
Field bean3 = Bean1.class.getDeclaredField("bean3"); DependencyDescriptor dd1 = new DependencyDescriptor(bean3, false); Object o = beanFactory.doResolveDependency(dd1, null, null, null); System.out.println(o); Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class); DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), true); Object o1 = beanFactory.doResolveDependency(dd2, null, null, null); System.out.println(o1); Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class); DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome, 0), true); Object o2 = beanFactory.doResolveDependency(dd3, null, null, null); System.out.println(o2);
 

CommonAnnotationBeanPostProcessor

添加对@Resource @PostConstruct @PreDestroy 的支持
context.registerBean(CommonAnnotationBeanPostProcessor.class); // @Resource @PostConstruct @PreDestroy
notion image
 

ConfigurationPropertiesBindingPostProcessor

添加对@Resource @PostConstruct @PreDestroy 的支持
/* java.home= java.version= */ @ConfigurationProperties(prefix = "java") public class Bean4 { private String home; private String version; public String getHome() { return home; } public void setHome(String home) { this.home = home; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } @Override public String toString() { return "Bean4{" + "home='" + home + '\'' + ", version='" + version + '\'' + '}'; } }
public static void main(String[] args) { // ⬇️GenericApplicationContext 是一个【干净】的容器 GenericApplicationContext context = new GenericApplicationContext(); // ⬇️用原始方法注册三个 bean context.registerBean("bean1", Bean1.class); context.registerBean("bean2", Bean2.class); context.registerBean("bean3", Bean3.class); context.registerBean("bean4", Bean4.class); context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // @Autowired @Value // context.registerBean(CommonAnnotationBeanPostProcessor.class); // @Resource @PostConstruct @PreDestroy // ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory()); // ⬇️初始化容器 context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例 System.out.println(context.getBean(Bean4.class)); // ⬇️销毁容器 context.close();
notion image

总结

  1. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能,这些扩展功能由 bean 后处理器来完成
  1. 每个后处理器各自增强什么功能
      • AutowiredAnnotationBeanPostProcessor 解析 @Autowired 与 @Value
      • CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy
      • ConfigurationPropertiesBindingPostProcessor 解析 @ConfigurationProperties
  1. 另外 ContextAnnotationAutowireCandidateResolver 负责获取 @Value 的值,解析 @Qualifier、泛型、@Lazy 等

后处理器排序

/* bean 后处理的的排序 */ public class TestProcessOrder { public static void main(String[] args) { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory); List<BeanPostProcessor> list = new ArrayList<>(List.of(new P1(), new P2(), new P3(), new P4(), new P5())); list.sort(beanFactory.getDependencyComparator()); list.forEach(processor->{ processor.postProcessBeforeInitialization(new Object(), ""); }); /* 学到了什么 1. 实现了 PriorityOrdered 接口的优先级最高 2. 实现了 Ordered 接口与加了 @Order 注解的平级, 按数字升序 3. 其它的排在最后 */ } @Order(1) static class P1 implements BeanPostProcessor { private static final Logger log = LoggerFactory.getLogger(P1.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.debug("postProcessBeforeInitialization @Order(1)"); return bean; } } @Order(2) static class P2 implements BeanPostProcessor { private static final Logger log = LoggerFactory.getLogger(P2.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.debug("postProcessBeforeInitialization @Order(2)"); return bean; } } static class P3 implements BeanPostProcessor, PriorityOrdered { private static final Logger log = LoggerFactory.getLogger(P3.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.debug("postProcessBeforeInitialization PriorityOrdered"); return bean; } @Override public int getOrder() { return 100; } } static class P4 implements BeanPostProcessor, Ordered { private static final Logger log = LoggerFactory.getLogger(P4.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.debug("postProcessBeforeInitialization Ordered"); return bean; } @Override public int getOrder() { return 0; } } static class P5 implements BeanPostProcessor { private static final Logger log = LoggerFactory.getLogger(P5.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.debug("postProcessBeforeInitialization"); return bean; } } }
notion image