Spring 高级 常见的Bean 后处理器
一、代码
package com.mangoubiubiu.show.a04; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; public class Bean1 { private static final Logger log = LoggerFactory.getLogger(Bean1.class); private Bean2 bean2; @Autowired public void setBean2(Bean2 bean2){ log.info("@Autowired 生效:{}",bean2); this.bean2=bean2; } private Bean3 bean3; public void setBean3(Bean3 bean3){ log.info("@Resource 生效:{}",bean3); this.bean3=bean3; } private String home; @Autowired public void setHomeAutowired(@Value("${JAVA_HOME}") String home){ log.info("Autowired@Value 生效:{}",home); this.home = home; } @Resource public void setHomeResource(@Value("${JAVA_HOME}") String home){ log.info("Resource@Value 生效:{}",home); this.home = home; } @PostConstruct public void initPostConstruct(){ log.info("@PostConstruct 生效"); } @PreDestroy public void initPreDestroy(){ log.info("@PreDestroy 生效"); } @Override public String toString() { return "Bean1{" + "bean2=" + bean2 + ", bean3=" + bean3 + ", home='" + home + '\'' + '}'; } }
package com.mangoubiubiu.show.a04; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public class Bean2 { }
package com.mangoubiubiu.show.a04; import org.springframework.stereotype.Component; @Component public class Bean3 { }
二、AutowiredAnnotationBeanPostProcessor
package com.mangoubiubiu.show.a04; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver; import org.springframework.context.support.GenericApplicationContext; public class A04Application { public static void main(String[] args) { // GenericApplicationContext 是一个【干净】的容器 GenericApplicationContext context = new GenericApplicationContext(); context.registerBean("bean1",Bean1.class); context.registerBean("bean2",Bean2.class); context.registerBean("bean3",Bean3.class); //自动装配后选者的解析器 context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //不给名字就会把包名类名做为添加名称 context.registerBean(AutowiredAnnotationBeanPostProcessor.class);//解析@Autowired 与 @Value // context.registerBean(CommonAnnotationBeanPostProcessor.class);//@Resource、@PostConstruct、@PreDestroy //初始化容器 context.refresh(); //销毁容器 context.close(); } }
三、CommonAnnotationBeanPostProcessor
package com.mangoubiubiu.show.a04; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver; import org.springframework.context.support.GenericApplicationContext; public class A04Application { public static void main(String[] args) { // GenericApplicationContext 是一个【干净】的容器 GenericApplicationContext context = new GenericApplicationContext(); context.registerBean("bean1",Bean1.class); context.registerBean("bean2",Bean2.class); context.registerBean("bean3",Bean3.class); //自动装配后选者的解析器 context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //不给名字就会把包名类名做为添加名称 // context.registerBean(AutowiredAnnotationBeanPostProcessor.class);//解析@Autowired 与 @Value context.registerBean(CommonAnnotationBeanPostProcessor.class);//@Resource、@PostConstruct、@PreDestroy //初始化容器 context.refresh(); //销毁容器 context.close(); } }
四、ConfigurationPropertiesBindingPostProcessor
package com.mangoubiubiu.show.a04; import org.springframework.boot.context.properties.ConfigurationProperties; @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; } }
package com.mangoubiubiu.show.a04; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver; import org.springframework.context.support.GenericApplicationContext; public class A04Application { public static void main(String[] args) { // GenericApplicationContext 是一个【干净】的容器 GenericApplicationContext context = new GenericApplicationContext(); 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()); //解析 @ConfigurationProperties //初始化容器 context.refresh(); System.out.println(context.getBean("bean4")); //销毁容器 context.close(); } }
没有取到值 也就是说@ConfigurationProperties 并未生效
添加后处理器发现生效了
二、总结
- @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能,这些扩展功能由 bean 后处理器来完成
- 每个后处理器各自增强什么功能
- AutowiredAnnotationBeanPostProcessor 解析 @Autowired 与 @Value ----执行时机 在依赖注入阶段解析@Autowired 与 @Value
- CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy ----执行时机 在依赖注入阶段负责解析 @Resource,初始化前解析@PostConstruct,销毁前负责解析@PreDestroy
- ConfigurationPropertiesBindingPostProcessor 解析 @ConfigurationProperties ----执行时机 初始前执行属性绑定