学习目标:
主程序类
- @SpringBootApplication
- public class A03Application {
- public static void main(String[] args) {
- ConfigurableApplicationContext context = SpringApplication.run(A03Application.class, args);
- context.close();
- }
- }
实体类
- @Component
- public class LifeCycleBean {
- private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);
-
- public LifeCycleBean() {
- log.debug("构造");
- }
-
- @Autowired
- //注入环境变量JAVA_HOME的值
- public void autowire(@Value("${JAVA_HOME}") String home) {
- log.debug("依赖注入: {}", home);
- }
-
- @PostConstruct
- public void init() {
- log.debug("初始化");
- }
-
- @PreDestroy
- public void destroy() {
- log.debug("销毁");
- }
- }
启动主程序类,结果:
- com.itheima.a03.LifeCycleBean - 构造
- [DEBUG] 09:37:46.542 [main] com.itheima.a03.LifeCycleBean - 依赖注入: D:\developer_tools\jdk\1.8.0_131
- [DEBUG] 09:37:46.545 [main] com.itheima.a03.LifeCycleBean - 初始化
- [DEBUG] 09:37:48.370 [main] com.itheima.a03.LifeCycleBean - 销毁
使用Bean后处理器在前后提供扩展
- @Component
- public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
-
- private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
-
- @Override
- public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean"))
- log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
- //返回null则保持原有对象不变
- return null;
- }
-
- @Override
- public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean")) {
- log.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
- //return false;
- }
- //返回 true 则继续依赖注入
- return true;
- }
-
- @Override
- public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean"))
- log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
- return pvs;
- }
-
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean"))
- log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean"))
- log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
- return bean;
- }
-
-
- @Override
- public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
- if (beanName.equals("lifeCycleBean"))
- log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy");
- }
-
- }
创建前后的增强
postProcessBeforeInstantiation
这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
postProcessAfterInstantiation
这里如果返回 false 会跳过依赖注入阶段
依赖注入前的增强
postProcessProperties
如 @Autowired、@Value、@Resource
初始化前后的增强
postProcessBeforeInitialization
这里返回的对象会替换掉原本的 bean
如 @PostConstruct、@ConfigurationProperties
postProcessAfterInitialization
这里返回的对象会替换掉原本的 bean
如代理增强
销毁之前的增强
postProcessBeforeDestruction
如 @PreDestroy
结果:
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean
- com.itheima.a03.LifeCycleBean - 构造
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource
- com.itheima.a03.LifeCycleBean - 依赖注入: D:\developer_tools\jdk\1.8.0_131
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties
- com.itheima.a03.LifeCycleBean - 初始化
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强
- com.itheima.a03.MyBeanPostProcessor - <<<<<< 销毁之前执行, 如 @PreDestroy
- com.itheima.a03.LifeCycleBean - 销毁
- public class TestMethodTemplate {
-
- public static void main(String[] args) {
- MyBeanFactory beanFactory = new MyBeanFactory();
- beanFactory.getBean();
- }
-
- static class MyBeanFactory {
- public Object getBean() {
- Object bean = new Object();
- System.out.println("构造 " + bean);
- System.out.println("依赖注入 " + bean);
- System.out.println("初始化 " + bean);
- return bean;
- }
- }
-
- }
场景:刚开始只实现了基本的功能,后面需要对依赖注入的功能进行扩展, 需要支持@Autowired的解析,在原代码上去修改的话扩展性不好, 如果后面需要继续支持 @Resource注解解析,又去原代码修改,这种做法不是很好。
使用模板模式:固定不变的形成方法的主干,变化的部分抽象成接口,Spring底层也是这样做的,这里只是简单模拟了一下。
- public class TestMethodTemplate {
-
- public static void main(String[] args) {
- MyBeanFactory beanFactory = new MyBeanFactory();
- beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
- beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
- beanFactory.getBean();
- }
-
- static class MyBeanFactory {
- public Object getBean() {
- Object bean = new Object();
- System.out.println("构造 " + bean);
- System.out.println("依赖注入 " + bean);
- //实现功能的扩展
- for (BeanPostProcessor processor : processors) {
- processor.inject(bean);
- }
- System.out.println("初始化 " + bean);
- return bean;
- }
- //后处理器列表
- private List
processors = new ArrayList(); - //添加后处理器
- public void addBeanPostProcessor(BeanPostProcessor postProcessor){
- processors.add(postProcessor);
- }
- }
- static interface BeanPostProcessor {
- public void inject(Object bean);//对依赖注入阶段的扩展
- }
- }
- public class TestProcessOrder {
-
- public static void main(String[] args) {
- DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
- //注册处理器
- AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
-
- List
list = new ArrayList(Arrays.asList(new P1(), new P2(), new P3(), new P4(), new P5())); - //通过AnnotationAwareOrderComparator比较
- list.sort(beanFactory.getDependencyComparator());
-
- list.forEach(processor->{
- //对bean执行处理器
- processor.postProcessBeforeInitialization(new Object(), "");
- });
-
- }
-
- @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;
- }
- }
- }
结果
- com.itheima.a03.TestProcessOrder$P3 - postProcessBeforeInitialization PriorityOrdered
- com.itheima.a03.TestProcessOrder$P4 - postProcessBeforeInitialization Ordered
- com.itheima.a03.TestProcessOrder$P1 - postProcessBeforeInitialization @Order(1)
- com.itheima.a03.TestProcessOrder$P2 - postProcessBeforeInitialization @Order(2)
- com.itheima.a03.TestProcessOrder$P5 - postProcessBeforeInitialization
debug发现 beanFactory.getDependencyComparator() 的结果是 AnnotationAwareOrderComparator,来看看这个比较器的底层原理,更好的理解底层如何排序。
AnnotationAwareOrderComparator是Spring内部的核心排序组件,通过这个类,可以对实现了PriorityOrdered、Ordered以及被@Order注解修饰的类进行统一的排序。
排序数字:比较规则-越小的数字优先级越高,越大的数字优先级越低。
order接口
- public interface Ordered {
- // 最高的优先级,实际数值为Integer的最小值
- int HIGHEST_PRECEDENCE = -2147483648;
- // 最低的优先级,实际数值为Integer的最大值
- int LOWEST_PRECEDENCE = 2147483647;
-
- int getOrder();
- }
AnnotationAwareOrderComparator继承自OrderComparator,而OrderComparator则直接实现了Comparator,所以入口就在OrderComparator#compare中。
- public int compare(@Nullable Object o1, @Nullable Object o2) {
- // 调用内部的私有方法doCompare
- return this.doCompare(o1, o2, (OrderComparator.OrderSourceProvider)null);
- }
-
- private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderComparator.OrderSourceProvider sourceProvider) {
- // 优先PriorityOrdered
- boolean p1 = (o1 instanceof PriorityOrdered);
- boolean p2 = (o2 instanceof PriorityOrdered);
-
- // p1实现了PriorityOrdered,但是p2没实现PriorityOrdered,则p1优先级更高
- if (p1 && !p2) {
- return -1;
- }
- // p1没实现了PriorityOrdered,但是p2实现了PriorityOrdered,则p2优先级更高
- else if (p2 && !p1) {
- return 1;
- }
-
- // 方法执行到此,说明两者要么都实现了PriorityOrdered,或者都没实现PriorityOrdered,
- //则此时不再比较PriorityOrdered,开始比较order值
- // 调用内部私有方法getOrder
- int i1 = getOrder(o1, sourceProvider);
- int i2 = getOrder(o2, sourceProvider);
- return Integer.compare(i1, i2);
- }
- private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
- Integer order = null;
- // 由于doCompare方法传入的第二个参数OrderSourceProvider为空,所以这里的逻辑不会执行
- if (obj != null && sourceProvider != null) {
- Object orderSource = sourceProvider.getOrderSource(obj);
- if (orderSource != null) {
- if (orderSource.getClass().isArray()) {
- Object[] sources = ObjectUtils.toObjectArray(orderSource);
- for (Object source : sources) {
- order = findOrder(source);
- if (order != null) {
- break;
- }
- }
- }
- else {
- order = findOrder(orderSource);
- }
- }
- }
- // 直接执行这里的,调用getOrder继续获取order
- return (order != null ? order : getOrder(obj));
- }
- protected int getOrder(@Nullable Object obj) {
- if (obj != null) {
- // 调用findOrder从对象中获取order,该方法在AnnotationAwareOrderComparator中被覆写了
- Integer order = findOrder(obj);
- if (order != null) {
- return order;
- }
- }
- // 获取不到,则说明对象类没有实现Ordered,且没有@Order注解,默认最低优先级
- return Ordered.LOWEST_PRECEDENCE;
- }
findOrder方法是定义在OrderComparator中的,但是子类AnnotationAwareOrderComparator又进行了覆写。
先看看父类OrderComparator#findOrder方法
- protected Integer findOrder(Object obj) {
- // 可以看出仅仅只是从实现Ordered接口入手,获取其getOrder的值
- return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
- }
再看看子类覆写的AnnotationAwareOrderComparator#findOrder
- protected Integer findOrder(Object obj) {
- // 优先调用父类OrderComparator#findOrder,即从Ordered接口入手,获取其getOrder的值
- Integer order = super.findOrder(obj);
- if (order != null) {
- return order;
- }
- // 获取不到时,再调用内部私有方法findOrderFromAnnotation从注解获取order
- return findOrderFromAnnotation(obj);
- }
- private Integer findOrderFromAnnotation(Object obj) {
- AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
- MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY);
- // 从@Order注解中获取order值,该方法会将class作为缓存key放入缓存map中,即同一个类第二次无需再读取注解的值
- Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
- if (order == null && obj instanceof DecoratingProxy) {
- return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
- }
- return order;
- }
可以看出,内部是通过工具类OrderUtils获取排序注解的值
- static Integer getOrderFromAnnotations(AnnotatedElement element, MergedAnnotations annotations) {
- // 由findOrderFromAnnotation可知,传入的必然是class对象
- if (!(element instanceof Class)) {
- return findOrder(annotations);
- }
- // 从缓存中以AnnotatedElement(此处为class)作为缓存key,获取order
- Object cached = orderCache.get(element);
- if (cached != null) {
- // 缓存不为空,直接返回order
- return (cached instanceof Integer ? (Integer) cached : null);
- }
- // 缓存为空,调用内部私有方法findOrder继续获取order
- Integer result = findOrder(annotations);
- // 将得到的order以key-AnnotatedElement,value-order放入缓存map中,
- //若result即order为空,则放入NOT_ANNOTATED(其实就是一个new Object())作为获取失败的
- orderCache.put(element, result != null ? result : NOT_ANNOTATED);
- return result;
- }
- private static Integer findOrder(MergedAnnotations annotations) {
- // 优先从@Order注解中获取order,获取成功直接返回其value
- MergedAnnotation
orderAnnotation = annotations.get(Order.class); - if (orderAnnotation.isPresent()) {
- return orderAnnotation.getInt(MergedAnnotation.VALUE);
- }
- // 用于获取@Priority注解的value(即javax.annotation.Priority)
- MergedAnnotation> priorityAnnotation = annotations.get(JAVAX_PRIORITY_ANNOTATION);
- if (priorityAnnotation.isPresent()) {
- return priorityAnnotation.getInt(MergedAnnotation.VALUE);
- }
- return null;
- }
总结:
1、实现PriorityOrdered优先级更高,都有PriorityOrdered则比较各自的order(PriorityOrdered其实只是一个标记,虽然它继承自Ordered,但是没有扩展任何方法)
2、都没有PriorityOrdered,则比较Ordered#getOrder、@Order#value以及javax.annotation.Priority,值小的优先级更高
(此时,优先获取接口的Ordered#getOrder,若有则不再获取注解的@Order#value,若没有再获取注解@Order#value的值,若依然没有则尝试获取javax.annotation.Priority的值,都没有则默认返回最低优先级Ordered.LOWEST_PRECEDENCE)
参考文章:详解Spring的核心排序类-AnnotationAwareOrderComparator
使用GenericApplicationContext原因:GenericApplicationContext 是一个【干净】的容器,【干净】指没有添加beanFactory处理器,bean处理器。
DefaultListableBeanFactory也可以,但是使用起来比较麻烦。
- public class A04Application {
- public static void main(String[] args) {
- 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);
-
-
- //ContextAnnotationAutowireCandidateResolver 负责获取 @Value 的值,解析 @Qualifier、泛型、@Lazy 等
- context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
- context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
-
- // 初始化容器
- context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例
-
- System.out.println(context.getBean(Bean4.class));
-
- // 销毁容器
- context.close();
-
- }
- }
- 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;
- }
-
- 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 {
- }
- @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 + '\'' +
- '}';
- }
- }
结果:@Resource,@PostConstruct,@PreDestroy注解没有被解析
- com.itheima.a04.Bean1 - @Value 生效: D:\developer_tools\jdk\1.8.0_131
- com.itheima.a04.Bean1 - @Autowired 生效: com.itheima.a04.Bean2@21507a04
- Bean4{home='null', version='null'}
1)添加CommonAnnotationBeanPostProcessor ,解析 @Resource、@PostConstruct、@PreDestroy
context.registerBean(CommonAnnotationBeanPostProcessor.class);
结果:发现先解析@Resource,后解析@Autowired,前面讲过,与后处理器顺序有关
- com.itheima.a04.Bean1 - @Resource 生效: com.itheima.a04.Bean3@1f1c7bf6
- com.itheima.a04.Bean1 - @Autowired 生效: com.itheima.a04.Bean2@691a7f8f
- com.itheima.a04.Bean1 - @Value 生效: D:\developer_tools\jdk\1.8.0_131
- com.itheima.a04.Bean1 - @PostConstruct 生效
- Bean4{home='null', version='null'}
- com.itheima.a04.Bean1 - @PreDestroy 生效
2)添加ConfigurationPropertiesBindingPostProcessor ,解析 @ConfigurationProperties
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
结果:Bean4的依赖被注入
- com.itheima.a04.Bean1 - @Resource 生效: com.itheima.a04.Bean3@1f1c7bf6
- com.itheima.a04.Bean1 - @Autowired 生效: com.itheima.a04.Bean2@691a7f8f
- com.itheima.a04.Bean1 - @Value 生效: D:\developer_tools\jdk\1.8.0_131
- com.itheima.a04.Bean1 - @PostConstruct 生效
- Bean4{home='D:\developer_tools\jdk\1.8.0_131\jre', version='1.8.0_131'}
- com.itheima.a04.Bean1 - @PreDestroy 生效
总结:
每个后处理器各自增强什么功能
AutowiredAnnotationBeanPostProcessor 解析 @Autowired 与 @Value
CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy
ConfigurationPropertiesBindingPostProcessor 解析 @ConfigurationProperties
另外 ContextAnnotationAutowireCandidateResolver 负责获取 @Value 的值,解析 @Qualifier、泛型、@Lazy 等
AutowiredAnnotationBeanPostProcessor 运行分析
- 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); // ${}的解析器
-
- AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
- processor.setBeanFactory(beanFactory);
-
- Bean1 bean1 = new Bean1();
- System.out.println(bean1);
- // 执行依赖注入 @Autowired
- processor.postProcessProperties(null, bean1, "bean1");
- System.out.println(bean1);
- }
- }
结果:执行了postProcessProperties方法后依赖被注入
- Bean1{bean2=null, bean3=null, home='null'}
- com.itheima.a04.Bean1 - @Value 生效: D:\developer_tools\jdk\1.8.0_131
- com.itheima.a04.Bean1 - @Autowired 生效: com.itheima.a04.Bean2@2473b9ce
- Bean1{bean2=com.itheima.a04.Bean2@2473b9ce, bean3=null, home='D:\developer_tools\jdk\1.8.0_131'}
postProcessProperties方法:
- /*
- 参数一:指定bean的每个属性的值,由于不需要,为null
- 参数二:被注入的目标
- 参数三:被注入的名字
- */
- public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
- InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
-
- try {
- //用反射给属性赋值
- metadata.inject(bean, beanName, pvs);
- return pvs;
- } catch (BeanCreationException var6) {
- throw var6;
- } catch (Throwable var7) {
- throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
- }
- }
下面对这个方法的步骤进行分解
步骤一:查找哪些属性、方法加了 @Autowired,结果封装成 InjectionMetadata
反射调用findAutowiringMetadata方法
- 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); // ${}的解析器
-
- 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);
- // 获取 Bean1 上加了 @Value @Autowired 的成员变量,方法参数信息
- InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);
- System.out.println(metadata);
- }
- }
debug查看metadata
如果我在Bean1类添加
- @Autowired
- private String aaa;
结果:size变为3了
步骤二:调用 InjectionMetadata 来进行依赖注入, 注入时按类型查找值
- metadata.inject(bean1, "bean1", null);
- System.out.println(bean1);
结果:
Bean1{bean2=com.itheima.a04.Bean2@3d0f8e03, bean3=null, home='D:\developer_tools\jdk\1.8.0_131'}
如何按类型查找值
- Field bean3 = Bean1.class.getDeclaredField("bean3");
- //spring内部将其封装成 DependencyDescriptor 对象
- //参数一:成员变量 参数二:是否必须
- DependencyDescriptor dd1 = new DependencyDescriptor(bean3, false);
- //根据成员变量的信息得到它的类型,进而根据类型找到容器中符合的bean
- Object o = beanFactory.doResolveDependency(dd1, null, null, null);
- System.out.println(o);
- //最后根据反射调用set方法给bean1
-
- //@Autowire在方法上
- Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
- //spring内部将其封装成 DependencyDescriptor 对象
- //MethodParameter 参数一:方法 参数二:方法的第几个参数
- DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), false);
- Object o2 = beanFactory.doResolveDependency(dd2, null, null, null);
- System.out.println(o2);
-
- Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
- DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome, 0), true);
- Object o3 = beanFactory.doResolveDependency(dd3, null, null, null);
- System.out.println(o3);
结果:
- com.itheima.a04.Bean3@5fbdfdcf
- com.itheima.a04.Bean2@2df9b86
- D:\developer_tools\jdk\1.8.0_131
总结:
AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata 用来获取某个 bean 上加了 @Value @Autowired 的成员变量,方法参数的信息,表示为 InjectionMetadata
InjectionMetadata 可以完成依赖注入
InjectionMetadata 内部根据成员变量,方法参数封装为 DependencyDescriptor 类型
有了 DependencyDescriptor,就可以利用 beanFactory.doResolveDependency 方法进行基于类型的查找