Spring高级49讲-第四讲:Bean后处理器笔记

第四讲:Bean后处理器

目录

第四讲:Bean后处理器

学习目标

一、常见的Bean后处理器

 1.1 AutowiredAnnotationBeanPostProcessor的Bean后处理器

 1.2  CommonAnnotationBeanPostProcessor

 1.3 ConfigurationPropertiesBindingPostProcessor

二、@Autowired bean后处理器执行分析

  2.1 准备工作

 2.2依赖注入前方法的源码

总结

1.讲解了bean的三个后处理器

2.postProcessProperties() 这个方法实际调用的源码



学习目标

1.Bean后处理器的作用:为Bean生命周期各个阶段提供扩展

2.常见的后处理器


一、常见的Bean后处理器

package com.itheima.a04;

import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;

/*
    bean 后处理器的作用
 */
public class A04 {
    public static void main(String[] args) {
        // ⬇️GenericApplicationContext 是一个【干净】的容器
        //干净---并没有跟我们添加一些后处理器    GenericApplicationContext-未注册的容器
        GenericApplicationContext context = new GenericApplicationContext();

        // ⬇️用原始方法注册三个 bean
        context.registerBean("bean1", Bean1.class);
        context.registerBean("bean2", Bean2.class);
        context.registerBean("bean3", Bean3.class);

        // ⬇️初始化容器
        context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例

        // ⬇️销毁容器
        context.close();

        /*
            学到了什么
                a. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能
                b. 这些扩展功能由 bean 后处理器来完成
         */
    }
}
package com.itheima.a04;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class Bean1 {
    private static final Logger log = LoggerFactory.getLogger(Bean1.class);

    private Bean2 bean2;

    @Autowired
    public void setBean2(Bean2 bean2) {
        log.debug("@Autowired 生效: {}", bean2);
        this.bean2 = bean2;
    }

    @Autowired
    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 + '\'' +
               '}';
    }
}
package com.itheima.a04;

public class Bean2 {
}

package com.itheima.a04;

public class Bean3 {
}

我们执行一下  看一下这些注解到底解析了没有

结果并没有打印bean1中的信息  说明注解还没有解析 

1.1 AutowiredAnnotationBeanPostProcessor的Bean后处理器

加入这个代码后  发现出现异常,默认的这个自动装配注解的bean后处理器是不支持值的依赖注入的 因此我们需要设置一下

 

 1.2  CommonAnnotationBeanPostProcessor

1.3 ConfigurationPropertiesBindingPostProcessor

 

 

 

 

总结

1. AutowiredAnnotationBeanPostProcessor 在依赖注入阶段解析@Autowired 和@value

2.CommonAnnotationBeanPostProcessor 在依赖注入阶段解析@Resource  在初始化前解析@PostConstruct   销毁前解析@preDestroy

3.ConfigurationPropertiesBindingPostProcessor 在初始化前解析 @ConfigurationProperties注解

二、@Autowired bean后处理器执行分析

  2.1 准备工作

package com.itheima.a04;

import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.StandardEnvironment;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

// AutowiredAnnotationBeanPostProcessor 运行分析
public class DigInAutowired {
    public static void main(String[] args) throws Throwable {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//        beanFactory.registerBeanDefinition(); //前面用的是这个  比较麻烦 添加bean我们用下面的方法
        beanFactory.registerSingleton("bean2", new Bean2()); // 不会走创建过程,依赖注入,初始化
        beanFactory.registerSingleton("bean3", new Bean3());
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); // @Value


        // 1. 查找哪些属性、方法加了 @Autowired, 这称之为 InjectionMetadata
      
        // 2. 调用 InjectionMetadata 来进行依赖注入, 注入时按类型查找值
//        metadata.inject(bean1, "bean1", null);
//        System.out.println(bean1);

        // 3. 如何按类型查找值
       

    }
}
为绑定bean后处理器前

绑定后 

 

2.2依赖注入前方法的源码

我们先找到metadata 

 因为metadata没有重写toString()我们使用断点debug查看

可以看出来 metadata中封装的就是@Autowired 和@Value的成员变量和方法 

 

调用 InjectionMetadata 来进行依赖注入, 注入时按类型查找值

这里我们发现home中的${}并没有解析  ---是因为我们创建的时候并没有创建一个${}的解析器 

总结

processor.postProcessProperties()  这个方法实际调用的就是

第一先找到metadata   

然后进行inject注入

 

metadata.inject(bean1, "bean1", null); 是如何按照类型查找的呢

   1 查找成员变量

 

Field bean3 = Bean1.class.getDeclaredField("bean3");
//DependencyDescriptor -- 依赖描述     通过成员变量的类型  找
DependencyDescriptor dd1=new DependencyDescriptor(bean3,false);
Object o = beanFactory.doResolveDependency(dd1, null, null, null);
System.out.println(o);

2.方法(值传入)

 

Method setHome =Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3=new DependencyDescriptor(new MethodParameter(setHome,0),false);
Object o3 = beanFactory.doResolveDependency
        (dd3,null,null,null);
System.out.println(o3);

 

3.方法 (对象)

 

 

如果容器中没有bean2对象   

 

方法中我们设置的是false 直接返回null  

如果设置为true  就会抛异常


总结

1.讲解了bean的三个后处理器

1. AutowiredAnnotationBeanPostProcessor 在依赖注入阶段解析@Autowired 和@value

2.CommonAnnotationBeanPostProcessor 在依赖注入阶段解析@Resource  在初始化前解析@PostConstruct   销毁前解析@preDestroy

3.ConfigurationPropertiesBindingPostProcessor 在初始化前解析 @ConfigurationProperties注解

2.postProcessProperties() 这个方法实际调用的源码

1.processor.postProcessProperties() 这个方法实际调用的就是
第一先找到metadata   然后进行inject注入

 2.inject的按照类型查找的原理 

     成员变量的依赖注入

     方法的依赖注入

     方法的值注入

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值