BeanFactory容器的实现

BeanFactory 容器的实现

BeanFactory 不会做的事情:

  • 不会主动调用 BeanFactoryPostProcessor
  • 不会主动调用(添加)BeanPostProcessor
  • 不会主动实例化单例对象(懒加载)
  • 不会解析BeanFactory,且不会解析 ${}#{} 表达式

手动向 BeanFactory 容器中注入 Bean 对象

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


public class BeanFactoryMainV1 {
    //TODO: 此时的 BeanFactory 缺乏解析 @Bean 和 @Configuration 等注解的能力
    public static void main(String[] args) {
        // 1. 默认的 BeanFactory 容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 2. 创建 BeanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyConfig.class).getBeanDefinition();
        // 3. 向容器中添加 BeanDefinition
        beanFactory.registerBeanDefinition("myConfig", beanDefinition);
        // 4. 输出容器中的 Bean
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }


    @Configuration
    static class MyConfig {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

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

    }

    static class Bean2 {
        private static final Logger LOGGER = LoggerFactory.getLogger(Bean2.class);

    }
}

为 BeanFactory 添加常用的后置处理器

后置处理器相当于 Spring 容器的插件,BeanFactory 容器本身的功能并没有多么丰富,很多功能都是通过后置处理器来进行实现的。

public class BeanFactoryMainV2 {
    //TODO: 后置处理器添加到BeanFactory工厂, 但是并没有运行
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        //解析 @Bean 和 @Configuration 等注解是其它类的功能
        // 为 BeanFactory 添加一些常用的后处理器, 可以使得能够解析注解
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyConfig.class).getBeanDefinition();
        beanFactory.registerBeanDefinition("myConfig", beanDefinition);
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }


    @Configuration
    static class MyConfig {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

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

    }

    static class Bean2 {
        private static final Logger LOGGER = LoggerFactory.getLogger(Bean2.class);

    }
}

将后置处理器添加到BeanFactory容器中

执行后置处理器的功能

BeanFactoryPostProcessor 和 BeanPostProcessor 两大类后置处理器

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;


public class BeanFactoryMainV3 {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyConfig.class).getBeanDefinition();
        beanFactory.registerBeanDefinition("myConfig", beanDefinition);

        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        // 先注册Bean, 然后使用后置处理器进行解析才有效. 如果上面的registerBeanDefinition在解析过程之后则无法解析成功
        // 遍历执行添加到 BeanFactory 中的 BeanFactoryPostProcessor
        Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        beanFactoryPostProcessorMap.forEach((key, value) -> {
            System.out.println("key = " + key);
            value.postProcessBeanFactory(beanFactory);
        });

        // BeanPostProcessor: Bean后置处理器, 用来处理类似@Autowired和@Resource等Bean对象的生命周期
        Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
        beanPostProcessorMap.forEach((key, value) -> {
            System.out.println("key = " + key);
            beanFactory.addBeanPostProcessor(value);
        });

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }


        // 在此之前, Bean对象只是简单加入到容器中, 并没有调用构造方法进行实例化
        System.out.println("################################################################################");

        Bean1 bean1 = beanFactory.getBean(Bean1.class);
        Bean2 bean2 = bean1.getBean2();
        System.out.println("bean2 = " + bean2);
    }


    @Configuration
    static class MyConfig {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

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

        public Bean1() {
            LOGGER.debug("Bean1构造函数");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return this.bean2;
        }
    }

    static class Bean2 {
        private static final Logger LOGGER = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            LOGGER.debug("Bean2构造函数");
        }
    }
}

执行后置处理器的功能

默认懒加载方式创建Bean

提前创建好所有的单例对象

package com.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;


public class BeanFactoryMainV4 {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyConfig.class).getBeanDefinition();
        beanFactory.registerBeanDefinition("myConfig", beanDefinition);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        beanFactoryPostProcessorMap.forEach((key, value) -> {
            System.out.println("key = " + key);
            value.postProcessBeanFactory(beanFactory);
        });
        Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
        beanPostProcessorMap.forEach((key, value) -> {
            System.out.println("key = " + key);
            beanFactory.addBeanPostProcessor(value);
        });
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        // 提前创建好所有的单例对象
        beanFactory.preInstantiateSingletons();
        System.out.println("################################################################################");

        Bean1 bean1 = beanFactory.getBean(Bean1.class);
        Bean2 bean2 = bean1.getBean2();
        System.out.println("bean2 = " + bean2);
    }


    @Configuration
    static class MyConfig {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

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

        public Bean1() {
            LOGGER.debug("Bean1构造函数");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return this.bean2;
        }
    }

    static class Bean2 {
        private static final Logger LOGGER = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            LOGGER.debug("Bean2构造函数");
        }
    }
}

提前创建容器中的Bean对象

后置处理器

AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory); 开始查看后置处理器

public abstract class AnnotationConfigUtils {
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                // 设置比较器, 用于对后置处理器进行排序, 进而确定解析顺序
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        // 解析@Configuration注解
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 解析@Autowired注解
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 解析@Resource注解(Common: Java中的注解)
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }

}

思考:

  1. @Autowired 的注入规则是什么?

    @Autowired 是根据类型进行注入,如果存在多个相同的类型 Bean,则再使用变量名去进行匹配,如果不存在,则进行报错。另外也可以不修改变量名,而使用 @Qualified 来指定匹配的 Bean 的name。

  2. 如果同时添加 @Autowired@Resource,那么哪个优先级高(或者说哪个生效)?

    默认不进行排序,而 @Autowired的后置处理器在前,所以先执行解析。如果通过代码对后置处理器进行排序的话,那优先级高的(order值小)的先解析执行,即 @Resource 执行。(只有排序后才和后置处理器的优先级(order)有关,order值越小,优先级越高,排序越靠前,越先解析)

    排序的核心逻辑:优先级越高,排序越靠前,比较器只是用来制定优先级规则,即什么情况下优先级高,可以是分数越高,也可以是序号越小

    // 排序接口,默认值越大,优先级越低(升序排序, 在前的优先级高)
    public interface Ordered {
        int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
        int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
        int getOrder();
    }
    
    public class ConfigurationClassPostProcessor{
        public int getOrder() {
            return Ordered.LOWEST_PRECEDENCE;
        }
    }
    
    public class AutowiredAnnotationBeanPostProcessor{
        private int order = Ordered.LOWEST_PRECEDENCE - 2;    
    }
    
    public class CommonAnnotationBeanPostProcessor{
        public CommonAnnotationBeanPostProcessor() {
            setOrder(Ordered.LOWEST_PRECEDENCE - 3);
            setInitAnnotationType(PostConstruct.class);
            setDestroyAnnotationType(PreDestroy.class);
            ignoreResourceType("javax.xml.ws.WebServiceContext");
    
            // java.naming module present on JDK 9+?
            if (jndiPresent) {
                this.jndiFactory = new SimpleJndiBeanFactory();
            }
        } 
    }
    

   转载规则


《BeanFactory容器的实现》 熊水斌 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
Redis实战 Redis实战
Redis 实战第一章 初识 Redis1.1 Redis 简介 Redis 是内存数据库,但可以通过 RDB 和 AOF 两种方式来支持数据持久化。 Redis 通过主从复制特性来扩展读性能(主服务器写,从服务器读) Redis 通过客户
2023-04-03
下一篇 
Netty Netty
零拷贝(性能优化) 零拷贝并不是不进行拷贝, 而是指0次CPU拷贝(从内核空间缓冲区->用户空间缓冲区)。而CPU拷贝是比DMA拷贝耗费的时间长得多, 所以减少CPU拷贝是提升性能的关键。 mmap内存映射方式适用于小数据,
2023-04-01
  目录