Spring原理

71 阅读3分钟

1.BeanFactory与ApplicationContext

image.png BeanFactory的功能:

  1. BeanFactory是spring中核心的一个顶层接口,是spring的核心容器

  2. 主要职责是生产bean

  3. 使用了简单工厂的设计模式,通过调用getBean(标识)获取一个Bean

  4. 有非常多的实现类,每个工厂都有不同的职责功能,最强大的工厂是DefaultListableBeanFactory。spring底层是使用DefaultListableBeanFactory进行生产bean

  5. 是ApplicationContext的父接口,主要的ApplicationContext实现都组合了BeanFactory的功能

  6. 控制反转、基本的依赖注入、bean的生命周期的各种功能都有BeanFactory的实现类提供

    以SpringBoot启动类代码举例

@SpringBootApplication 
public class Application { 
    public static void main(String[] args) {
        SpringApplication.run(Application.class); 
        System.out.println("启动完成"); 
        ConfigurableApplicationContext run = SpringApplication.run(Application.class); 
    } 
}

ApplicationContext的功能

run方法返回的结果是ConfigurableApplicationContext,这个类继承于ApplicationContext。

  • 从UML图上看出,Spring的核心容器BeanFactory是ApplicationContext的父接口。
  • ApplicationContext实现组合了BeanFactory的功能,并且扩展了BeanFactory的功能。
@SpringBootApplication
public class SpringStudyApplication {

    public static void main(String[] args) throws IOException {

        ConfigurableApplicationContext context = SpringApplication.run(SpringStudyApplication.class, args);

        System.out.println("*********扩展MessageResource*********");
        System.out.println("*********功能:国际化*********");
        System.out.println(context.getMessage("hi", null, Locale.CHINESE));
        System.out.println(context.getMessage("hi", null, Locale.ENGLISH));

        System.out.println("*********扩展ResourcePatternResolver*********");
        System.out.println("*********功能:获取资源*********");
        Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource:resources){
            System.out.println(resource);
        }

        System.out.println("*********扩展EnvironmentCapable*********");
        System.out.println("*********功能:获取配置信息*********");
        context.getEnvironment().getProperty("java_home");
        context.getEnvironment().getProperty("server.port");
    }
}

输出结果

image.png

BeanFactory的实现

①先创建beanfactory的核心容器实例对象,DefaultListableBeanFactory是bean加载的核心部分,是Spring注册及加载的默认实现。

②创建bean定义对象beanDefinition,bean的描述信息包括(class,scope,初始化方法,销毁方法),创建Config,bean1,bean2实例bean

③将bean定义对象beanDefinition注册到beanfactory,此时beanfactory中就有了一个名为config的bean

public class TestBeanFactory {
    public static void main(String[] args) {
        //DefaultListableBeanFactory是bean加载的核心部分,是Spring注册及加载的默认实现
        //刚创建好,DefaultListableBeanFactory内部没有任何bean定义
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //bean的定义(class,scope,初始化方法,销毁方法)
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class)
                .setScope("singleton").getBeanDefinition();
        //注册,,完成以后beanFactory里面就多了一个名字为config的bean
        beanFactory.registerBeanDefinition("config",beanDefinition);
        for (String name : beanFactory.getBeanDefinitionNames()) {
        System.out.println(name);
        }
    }
    @Configuration
    static class Config{
        @Bean
        public Bean1 bean1(){return new Bean1();}
        @Bean
        public Bean2 bean2(){return new Bean2();}
    }

    static class Bean1{
            public Bean1(){
                System.out.println("构造Bean1");
            }

            @Autowired
            private Bean2 bean2;
            public Bean2 getBean2(){
                return bean2;
            }
    }

    static class Bean2{
        public Bean2(){
            System.out.println("构造Bean2");
        }
    }
}

输出结果:

image.png

但此时,只是将名为Config的类注册到了beanfactory中,并不能解析其中@Bean和@Config注解的功能

④给beanfactory添加一些bean的后处理器

//给 beanfactory添加一些常用的后处理器,
//internalConfigurationAnnotationProcessor处理@Configuration注解
//internalAutowiredAnnotationProcessor处理@Autowired注解
//internalCommonAnnotationProcessor处理@Resource注解
//internalEventListenerProcessor
//internalEventListenerFactory
// 有了后处理器就可以解析注解的能力(解析@Configuration,@Bean等)
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

//根据一个类型获取多个bean
//BeanFactory后处理器的主要功能,补充了一些bean的定义
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class)
        .values()
            .stream()
            .forEach(beanFactoryPostProcessor->{
                //执行beanFactory后处理器
                beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
            });

输出结果:

image.png

但此时,不能解析@Autowried注解

System.out.println(beanFactory.getBean("bean2"));
System.out.println(beanFactory.getBean(Bean1.class).getBean2());

输出结果:成功输出bean1中的bean2

image.png

添加Bean后处理器,对@Autowired @Resource进行解析处理

//添加Bean后处理器,对@Autowired @Resource进行解析处理
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

输出结果:成功输出bean1中的bean2

image.png

//提前构造号所有的单例对象,不加此代码,则使用bean时才会创建bean
beanFactory.preInstantiateSingletons();