Spring底层原理(三)

Spring底层原理(三)

Bean的生命周期
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        context.close();
    }
}

@Slf4j
@Component
public class LifeCycleBean {
    public LifeCycleBean(){
        log.info("构造");
    }

    @Autowired
    public void autowire(@Value("${JAVA_HOME}") String home){
        log.info("依赖注入:{}",home);
    }

    @PostConstruct
    public void init(){
        log.info("初始化");
    }

    @PreDestroy
    public void destroy(){
        log.info("销毁");
    }
}

启动容器后会得到以下结果

Spring底层原理(三)_第1张图片

Bean的生命周期为:构造方法 -> 依赖注入->初始化 ->销毁

与Bean生命周期相关的后置处理器

PostProcessor中文意思为后置处理器

InstantiationAwareBeanPostProcessorDestructionAwareBeanPostProcessor都是BeanPostProcessor的子接口

@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.info("<<<< 销毁前执行,如@PreDestory");
        }
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 实例化之前执行,这里返回的对象会替换掉原本的bean");
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 实例化后执行,这里返回false会跳过依赖注入阶段");
        }
        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;
    }
}

Spring底层原理(三)_第2张图片

Bean后置处理器与模板方法模式
public class MethodTemplateTest {
    public static void main(String[] args) {
        MyBeanFactory factory = new MyBeanFactory();
        factory.addProcessor(bean -> System.out.println("解析@Autowired"));
        factory.addProcessor(bean -> System.out.println("解析@Resources"));
        factory.getBean();
    }

    static class MyBeanFactory {
        private List<BeanPostProcessor> processors = new ArrayList<>();

        public void addProcessor(BeanPostProcessor postProcessor) {
            processors.add(postProcessor);
        }

        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;
        }
    }

    interface BeanPostProcessor {
        void inject(Object bean);//对依赖注入阶段进行拓展
    }
}
  • 将代码中不确定的部分抽象成接口,供后续拓展
常见的bean后置处理器
public class A4Application {
    public static void main(String[] args) {
        //GenericApplicationContext是一个干净的容器,没有添加BeanFactory后置处理器和Bean后置处理器
        GenericApplicationContext context = new GenericApplicationContext();
        //注册bean
        context.registerBean("bean1",Bean1.class);
        context.registerBean("bean2",Bean2.class);
        context.registerBean("bean3",Bean3.class);
        
        //初始化容器
        context.refresh();//执行beanFactory后置处理器,添加bean后置处理器,初始化所有单例bean

        //销毁容器
        context.close();
    }
}

添加AutowiredAnnotationBeanPostProcessor

context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new    ContextAnnotationAutowireCandidateResolver());
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
  • ContextAnnotationAutowireCandidateResolver:用于支持解析@Value
  • AutowiredAnnotationBeanPostProcessor:该处理器用于解析@Autowired @Value

在这里插入图片描述

添加CommonAnnotationBeanPostProcessor

context.registerBean(CommonAnnotationBeanPostProcessor.class);
  • CommonAnnotationBeanPostProcessor:用于解析@Resurce @PostConstruct @PreDestroy
ConfigurationPropertiesBindingPostProcessor.register(context);
  • ConfigurationPropertiesBindingPostProcessor:用于解析@ConfigurationProperties
Autowired后处理器执行分析
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);//需要从容器中查找依赖
Bean1 bean1 = new Bean1();
System.out.println(bean1);//Bean1{bean2=null, bean3=null, home='null'}
//参数1:需要注入的值,null则从容器中获取 参数2:被注入的目标
processor.postProcessProperties(null,bean1,"bean1");

在这里插入图片描述

通过反射访问InjectionMetadata中的信息

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的成员变量 方法参数信息

Spring底层原理(三)_第3张图片

如何查找依赖?

//根据field获取field对应的type,然后容factory中查找
Field bean3 = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor dd1 = new DependencyDescriptor(bean3, false);
Object o = beanFactory.doResolveDependency(dd1, null, null, null);
//根据方法参数查找依赖
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
//创建依赖描述器,按照方法参数查找依赖,需要一个MethodParameter对象,参数2为参数的索引
DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), true);
Object o2 = beanFactory.doResolveDependency(dd2, null, null, null);

//匹配@Value
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);

你可能感兴趣的:(Spring,spring,java,后端)