Spring底层原理学习笔记--第四讲--(常见bean后处理器与@Autowired bean后处理器执行分析)

常见bean后处理器

A04Application.java

package com.lucifer.itheima.a04;

import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;


public class A04Application {
    public static void main(String[] args) {
        // GenericApplicationContext 是一个【干净】的容器
        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);


        //        输出结果为
//        15:43:48.956 [main] INFO com.lucifer.itheima.a04.Bean1 - @Value 生效
//        15:43:48.963 [main] INFO com.lucifer.itheima.a04.Bean1 - @Autowired 生效
        context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);  //处理@Autowired @Value注解的依赖注入

        // 输出结果为
//        16:04:48.955 [main] INFO com.lucifer.itheima.a04.Bean1 - @Resource 生效:com.lucifer.itheima.a04.Bean3@6ee52dcd
//        16:04:48.956 [main] INFO com.lucifer.itheima.a04.Bean1 - @PostConstruct 生效
//        16:04:48.967 [main] INFO com.lucifer.itheima.a04.Bean1 - @PreDestroy 生效
        context.registerBean(CommonAnnotationBeanPostProcessor.class);  //处理@Resource @PostConstruct @PreDestroy的依赖注入

//        ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory()); //处理@ConfigurationProperties的依赖注入
        // 初始化容器
        context.refresh();  // 执行beanFactory后处理器,添加bean后处理器,初始化所有单例

        System.out.println(context.getBean(Bean4.class));
        // 销毁容器
        context.close();
    }
}

Bean1.java

package com.lucifer.itheima.a04;

import lombok.extern.slf4j.Slf4j;
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;


@Slf4j
public class Bean1 {

    private Bean2 bean2;

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

    private Bean3 bean3;

    @Resource
    public void setBean3(Bean3 bean3) {
        log.info("@Resource 生效:{}",bean3);
        this.bean3 = bean3;
    }

    public String home;

    @Autowired
    public void setHome(@Value("${JAVA_HOME}") String home){
        log.info("@Value 生效:{}",home);
        this.home = home;
    }

    @PostConstruct
    public void init(){
        log.info("@PostConstruct 生效");
    }

    @PreDestroy
    public void destroy(){
        log.info("@PreDestroy 生效");
    }

    @Override
    public String toString() {
        return "Bean1{" + "bean2=" + bean2 + ", bean3=" + bean3 + ", home='" + home + '\'' + '}';
    }
}

Bean2.java

package com.lucifer.itheima.a04;


public class Bean2 {
}

Bean3.java

package com.lucifer.itheima.a04;


public class Bean3 {
}

Bean4.java

package com.lucifer.itheima.a04;

import org.springframework.boot.context.properties.ConfigurationProperties;


/*
    java.home=
    java.version=
 */

@ConfigurationProperties(prefix = "java")
public class Bean4 {

    private String home;

    private String version;

    public String getHome(){
        return home;
    }

    public void setHome(){
        this.home=home;
    }

    public String getVersion(){
        return version;
    }

    public void setVersion(){
        this.version=version;
    }
}


@Autowired bean后处理器执行分析

package com.lucifer.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.registerSingleton("bean2",new Bean2()); //创建过程,依赖注入,初始化
        beanFactory.registerSingleton("bean3",new Bean3());
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //解析@Value注解
        beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders); //${}的解析器

        //1.查找哪些属性、方法加了@Autowired,这称之为InjectionMetadata
        AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
        processor.setBeanFactory(beanFactory);

        Bean1 bean1 = new Bean1();
        // 执行结果为
        //Bean1{bean2=null, bean3=null, home='null'}
//        System.out.println(bean1);
        processor.postProcessProperties(null,bean1,"bean1");  //执行依赖注入@Autowired @Value
        //执行结果为
        //17:23:33.456 [main] INFO com.lucifer.itheima.a04.Bean1 - @Autowired 生效:com.lucifer.itheima.a04.Bean2@6fd02e5
        //17:23:33.464 [main] INFO com.lucifer.itheima.a04.Bean1 - @Value 生效:${JAVA_HOME}
        //Bean1{bean2=com.lucifer.itheima.a04.Bean2@6fd02e5, bean3=null, home='${JAVA_HOME}'}
//        System.out.println(bean1);

        Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod(
            "findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
        findAutowiringMetadata.setAccessible(true);
        InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1",
                                                                                       Bean1.class, null);//获取Bean1
        // 上加了@Value @Autowired的成员变量,方法参数信息
        System.out.println(metadata);

        //2.调用InjectionMetadata,来进行依赖注入,注入时按类型查找值
        metadata.inject(bean1,"bean1",null);

        //输出结果为
        //Bean1{bean2=com.lucifer.itheima.a04.Bean2@3c0f93f1, bean3=null, home='E:\JDKg\jdk1.8'}
        System.out.println(bean1);

        //3.如何按类型查找值
        Field bean3 = Bean1.class.getDeclaredField("bean3");
        DependencyDescriptor dd1 = new DependencyDescriptor(bean3,false);
        Object o = beanFactory.doResolveDependency(dd1,null,null,null);
        //输出结果为
        //com.lucifer.itheima.a04.Bean3@18eed359
        System.out.println(o);

        Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
        DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2,0),false);
        beanFactory.doResolveDependency(dd2,null,null,null);
        Object o1 = beanFactory.doResolveDependency(dd2,null,null,null);
        // 输出结果为
        //com.lucifer.itheima.a04.Bean2@3c0f93f1
        System.out.println(o1);

        Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
        DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome,0),true);
        Object o2 = beanFactory.doResolveDependency(dd3,null,null,null);
        // 输出结果为
        //E:\JDK\jdk1.8
        System.out.println(o2);


    }
}

你可能感兴趣的:(spring,学习,笔记)