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 方法进行基于类型的查找

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小鲁蛋儿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值