一、Bean的生命周期
学习目标:
- Spring bean 生命周期各个阶段
- 模板设计模式
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
总结:
-
AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata 用来获取某个 bean 上加了 @Value @Autowired 的成员变量,方法参数的信息,表示为 InjectionMetadata
-
InjectionMetadata 可以完成依赖注入
-
InjectionMetadata 内部根据成员变量,方法参数封装为 DependencyDescriptor 类型
-
有了 DependencyDescriptor,就可以利用 beanFactory.doResolveDependency 方法进行基于类型的查找