Spring原理学习(二)Bean的生命周期与Bean后处理器

一、Bean的生命周期

学习目标:

  1. Spring bean 生命周期各个阶段
  2. 模板设计模式

Bean生命周期:

1、代码演示

主程序类

@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       - 销毁 

2、模板方法设计模式

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<BeanPostProcessor> processors = new ArrayList();
        //添加后处理器
        public void addBeanPostProcessor(BeanPostProcessor postProcessor){
            processors.add(postProcessor);
        }
    }
    static interface BeanPostProcessor {
        public void inject(Object bean);//对依赖注入阶段的扩展
    }
}

3、bean 后处理器的排序

public class TestProcessOrder {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //注册处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        List<BeanPostProcessor> 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,来看看这个比较器的底层原理,更好的理解底层如何排序。

4、AnnotationAwareOrderComparator原理

1)AnnotationAwareOrderComparator是什么?

AnnotationAwareOrderComparator是Spring内部的核心排序组件,通过这个类,可以对实现了PriorityOrdered、Ordered以及被@Order注解修饰的类进行统一的排序。

2)主要排序组件类介绍

  • OrderComparator:排序器基类,实现了Comparator,排序规则仅支持PriorityOrdered、Ordered,不支持@Order。
  • AnnotationAwareOrderComparator:继承自OrderComparator,在OrderComparator排序的基础上,增加了对排序类的@Order注解的支持,但是若既实现Ordered接口,又有@Order注解时,则优先从接口实现中获取值。实现原理主要还是覆写了OrderComparator#findOrder,增加了从注解中获取order的方法。
  • Ordered:排序接口,内有getOrder,用于给实现类返回自己的order;
  • PriorityOrdered:继承自Ordered,但是没有扩展任何方法,可以被视为一个标记。
  • Order:即@Order,是spring的注解,其value就是配置的order。
  • javax.annotation.Priority:即@Priority,javax的规范注解,其value就是配置的order

排序数字:比较规则-越小的数字优先级越高,越大的数字优先级越低。

3)AnnotationAwareOrderComparator源码解析

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<Order> 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

二、Bean 后处理器

1、代码测试 Bean 后处理器作用

使用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 生效 

总结:

  • @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能,这些扩展功能由 bean 后处理器来完成
  • 每个后处理器各自增强什么功能

    • AutowiredAnnotationBeanPostProcessor 解析 @Autowired 与 @Value

    • CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy

    • ConfigurationPropertiesBindingPostProcessor 解析 @ConfigurationProperties

  • 另外 ContextAnnotationAutowireCandidateResolver 负责获取 @Value 的值,解析 @Qualifier、泛型、@Lazy 等

2、@Autowired bean 后处理器运行分析

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

总结:

  1. AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata 用来获取某个 bean 上加了 @Value @Autowired 的成员变量,方法参数的信息,表示为 InjectionMetadata

  2. InjectionMetadata 可以完成依赖注入

  3. InjectionMetadata 内部根据成员变量,方法参数封装为 DependencyDescriptor 类型

  4. 有了 DependencyDescriptor,就可以利用 beanFactory.doResolveDependency 方法进行基于类型的查找

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鲁蛋儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值