首页 > 其他分享 >Spring 高级 AutowiredAnnotationBeanPostProcessor 运行分析

Spring 高级 AutowiredAnnotationBeanPostProcessor 运行分析

时间:2022-08-16 15:23:00浏览次数:83  
标签:beanFactory Spring org AutowiredAnnotationBeanPostProcessor 高级 bean1 new import

1、AutowiredAnnotationBeanPostProcessor 运行分析

AutowiredAnnotationBeanPostProcessor 的作用:AutowiredAnnotationBeanPostProcessor 解析 @Autowired@Value----执行时机 在依赖注入阶段解析@Autowired@Value

一、processor.postProcessProperties(null,bean1,"bean1")解析 @Autowired@Value

package com.mangoubiubiu.show.a04;


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

public class DigInAutowired {

    public static void main(String[] args) {

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerSingleton("bean2",new Bean2());//创建过程,依赖注入,初始化
        beanFactory.registerSingleton("bean3",new Bean3());

        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//value

        //1、查找哪些属性、方法加了@Autowired,这称之为InjectionMetadata
        AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
        //设置bean 工厂 让bean工厂去找Bean
        processor.setBeanFactory(beanFactory);

        //自己创建一个bean1 自己创建的并没有依赖注入
        Bean1 bean1 = new Bean1();

        System.out.println(bean1);

        processor.postProcessProperties(null,bean1,"bean1");

        System.out.println(bean1);


    }
}
package com.mangoubiubiu.show.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.info("@Autowired 生效:{}",bean2);
        this.bean2=bean2;
    }


    private Bean3 bean3;

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


    private String home;

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

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

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

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


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

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

 

 

package com.mangoubiubiu.show.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.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class DigInAutowired {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerSingleton("bean2",new Bean2());//创建过程,依赖注入,初始化
        beanFactory.registerSingleton("bean3",new Bean3());

        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//value

        //1、查找哪些属性、方法加了@Autowired,这称之为InjectionMetadata
        AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
        //设置bean 工厂 让bean工厂去找Bean
        processor.setBeanFactory(beanFactory);

        //自己创建一个bean1 自己创建的并没有依赖注入
        Bean1 bean1 = new Bean1();

        System.out.println(bean1);

//        processor.postProcessProperties(null,bean1,"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);
        System.out.println(bean1);


    }
}

三、metadata.inject(bean1,"bean1",null); 进行依赖注入

package com.mangoubiubiu.show.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.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.core.env.StandardEnvironment;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

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();
        //设置bean 工厂 让bean工厂去找Bean
        processor.setBeanFactory(beanFactory);

        //自己创建一个bean1 自己创建的并没有依赖注入
        Bean1 bean1 = new Bean1();

        System.out.println(bean1);

//        processor.postProcessProperties(null,bean1,"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);
        //进行依赖注入
        metadata.inject(bean1,"bean1",null);
        System.out.println(metadata);
        System.out.println(bean1);
    }
}

总结 :AutowiredAnnotationBeanPostProcessor 执行依赖注入的时候,实际上是先调用了postProcessProperties方法,而postProcessProperties方法内部 分为2步去进行依赖注入,第一步是用findAutowiringMetadata方法找到某个类型中标注了@Autowired 方法 成员变量 收集起来,信息叫做InjectionMetadata,找到信息后 InjectionMetadata 执行 inject 才完成反射调用 进行依赖注入。

 

标签:beanFactory,Spring,org,AutowiredAnnotationBeanPostProcessor,高级,bean1,new,import
From: https://www.cnblogs.com/mangoubiubiu/p/16591665.html

相关文章

  • Springboot基础知识 (19) - 在 Spring Boot 项目里使用 JUnit
    在开发中,单元测试(UnitTesting)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。简单来说,就是测试数据的......
  • 深入理解Spring事件机制(一):广播器与监听器的初始化
    前言Spring从3.x开始支持事件机制。在Spring的事件机制中,我们可以令一个事件类继承ApplicationEvent类,然后将实现了ApplicationListener的Bean注册到spring......
  • SpringCloud知识点整理
    一、SpringCloud如何实现服务的注册?首先创建一个maven主工程。创建2个model工程:一个model工程作为服务注册中心,即EurekaServer,另一个作为EurekaClient。启动一个......
  • 20220816 springboot_idea_lombok_转Entity 生成的ToDominObject没有用有参构造方
    1问题:使用lombok,DDD设计思想整合mapStruct时,转Entity生成的ToDominObject没有用有参构造方法构造对象 2解决方案:2.1未解决_原因猜想因为生......
  • Spring的DI依赖注入
    xml中依赖注入beanbean标签下<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring......
  • 国产时序数据库IotDB安装、与SpringBoot集成
    一.简介:本文将完成一个真实业务中的设备上报数据的一个例子,完整的展示后台服务接收到设备上报的数据后,将数据添加到时序数据库,并且将数据查询出来的一个例子。本文所有代......
  • 数据库高级
    #创建视图createviewvw_stuasSELECTorder_no,shipping_id,payment,product_nameFROMmmall_orderINNERJOINmmall_order_itemUSING(order_no);#查看视图SELECT*......
  • SpringBoot之RestController注解
    @RestController=@Controller+@RequestBody概念@RestController用过SpringMVC的人都知道,这个注解是加在类上面的,作用域是整个类,加上之后,这个类里面所有的接口......
  • java过滤器(Filter)、Spring拦截器(Handler)
    首先,tomcat容器中有Servlet容器和Spring容器,java过滤器。Filter是在Servlet规范中定义的,是Servlet容器支持的;Handler是在Spring容器内的,是Spring框架支持的......
  • 监控项目指标-SpringBoot Actuator
    一、初识引入环境<!--引入监控功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star......