Spring底层原理学习笔记--第二讲--(BeanFactory实现与ApplicaitonContext实现)

BeanFactory实现

package com.lucifer.itheima.a02;

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


@Slf4j
public class  TestBeanFactory {

    public static void main(String[] args) {
        // 刚开始创建好,内部没有任何的bean
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //所以需要添加 bean 的定义(bean的定义有哪些特征:class(类型),scope,初始化,销毁),beanFactory根据bean的定义去创建bean的对象
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class)
            .setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config",beanDefinition);


        //给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        //BeanFactory 后处理器主要功能,补充了一些bean定义
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));

//        for (String name: beanFactory.getBeanDefinitionNames()) {
//            //输出结果为
//            //config
//            //org.springframework.context.annotation.internalConfigurationAnnotationProcessor
//            //org.springframework.context.annotation.internalAutowiredAnnotationProcessor
//            //org.springframework.context.annotation.internalCommonAnnotationProcessor
//            //org.springframework.context.event.internalEventListenerProcessor
//            //org.springframework.context.event.internalEventListenerFactory
//            //bean1
//            //bean2
//
//            //  如果没有
//            //  AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//            //         beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach
//            //         (beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
//            //没有这两句的话,输出结果为
//            //config
//            System.out.println(name);
//        }
//
//        // 输出结果为 14:22:55.758 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()
//        //null
//        //.getBean(Bean1.class)会创建bean1,所以会调用它的构造方法,打印了 构造 Bean1()
//        //.getBean2()的时候打印的是null,也就是依赖注入的功能没有生效
//        System.out.println(beanFactory.getBean(Bean1.class).getBean2());


        // Bean 后处理器,针对bean的生命周期的各个阶段提供扩展,例如 @Autowired @Resource...
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        for (String name: beanFactory.getBeanDefinitionNames()) {
            //输出结果为
            //config
            //org.springframework.context.annotation.internalConfigurationAnnotationProcessor
            //org.springframework.context.annotation.internalAutowiredAnnotationProcessor
            //org.springframework.context.annotation.internalCommonAnnotationProcessor
            //org.springframework.context.event.internalEventListenerProcessor
            //org.springframework.context.event.internalEventListenerFactory
            //bean1
            //bean2

            System.out.println(name);
        }

//        // 输出结果为
//        //14:47:12.014 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()
//        //14:47:12.023 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean2()
//        System.out.println(beanFactory.getBean(Bean1.class).getBean2());

        beanFactory.preInstantiateSingletons();//准备好所有单例
        //输出结果为
        //  14:53:51.891 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()
        //  14:53:51.900 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean2()
        //      ============================
        System.out.println("============================");
//        System.out.println(beanFactory.getBean(Bean1.class).getBean2());

        // 输出 com.lucifer.itheima.a02.TestBeanFactory$Bean3@55a1c291
        System.out.println(beanFactory.getBean(Bean1.class).getInter());


        /*
            学到了什么
            a. beanFactory 不会做的事
                1.不会主动调用BeanFactory后处理器
                2.不会主动添加Bean后处理器
                3.不会主动初始化单例
                4.不会解析beanFactory 还不会解析 ${}与#{}
            b. bean后处理器会有排序的逻辑
         */

    }


    @Configuration
    static class Config {

        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

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

        @Bean
        public Bean3 bean3() {return new Bean3();}

        @Bean
        public Bean4 bean4() {return new Bean4();}
    }

    interface Inter {}

    static class Bean3 implements Inter {}

    static class Bean4 implements Inter {}

    static class Bean1 {

        public Bean1() {
            log.info("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }

        @Autowired // 注入的是bean3  按类型注入 如果如果有多个类型一样的话,看成员变量的名字,这里名字是bean3,所以注入的是bean3
//        @Resource(name = "bean4") //注入的是bean4,因为指定了名字
        // 如果@Autowired注解和  @Resource(name = "bean4")注解同时存在的话,生效的是bean3,跟后处理器的顺序有关 @Autowired后置处理器优先级高于@Resource的,所以
        // @Autowired的先解析了
        private Inter bean3;

        public Inter getInter() {
            return bean3;
        }

    }


    static class Bean2 {

        public Bean2() {
            log.info("构造 Bean2()");
        }
    }
}


ApplicaitonContext实现

package com.lucifer.itheima.a02;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.Controller;


@Slf4j
public class A02Application {

    public static void main(String[] args) {
        //输出结果为
        //bean1
        //bean2
        //com.lucifer.itheima.a02.A02Application$Bean1@23fe1d71
        testClassPathXmlApplicationContext();
        testFileSystemXmlApplicationContext();

        //输出结果为
        //读取之前...
        //读取之后...
        //bean1
        //bean2
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        System.out.println("读取之前...");
        for (String name:beanFactory.getBeanDefinitionNames()){
            System.out.println(name);
        }
        System.out.println("读取之后...");
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(new ClassPathResource("b01.xml"));
        // 如果是FileSystemXmlApplicationContext()
        //reader.loadBeanDefinitions(new FileSystemResource("src\\main" +
                                                              "\\resources\\b01.xml"));
        for (String name: beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }


        //输出结果为
        //a02Application.Config
        //bean1
        //bean2
        //com.lucifer.itheima.a02.A02Application$Bean1@7adda9cc
        testAnnotationConfigurationContext();

//        testAnnotationConfigServletWebServerApplicationContext();
    }

    // 较为经典的容器,基于classpath下xml格式的配置文件来创建
    private static void testClassPathXmlApplicationContext() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("b01.xml");

        for (String name: context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }

    // 基于磁盘路径下xml格式的配置文件来创建
    private static void testFileSystemXmlApplicationContext() {
//        FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("D:\\DemoProject\\MyAccessSdk" +
//                                                                                          "\\access\\src\\main" +
//                                                                                          "\\resources\\b01.xml");
        FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src\\main" +
                                                                                          "\\resources\\b01.xml");
        for (String name: context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());

    }

    // 较为经典的容器,基于java配置类来创建
    private static void testAnnotationConfigurationContext() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        for (String name: context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());

    }

    // 较为经典的容器,基于java配置类来创建,用于web环境
    private static void testAnnotationConfigServletWebServerApplicationContext() {

        AnnotationConfigServletWebServerApplicationContext context =
            new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);

    }

    @Configuration
    static class WebConfig {
        @Bean
        public ServletWebServerFactory servletWebServerFactory() {
            return new TomcatServletWebServerFactory();
        }
        @Bean
        public DispatcherServlet dispatcherServlet(){
            return new DispatcherServlet();
        }
        @Bean
        public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){
            return new DispatcherServletRegistrationBean(dispatcherServlet,"/");
        }
        @Bean("/hello")
        public Controller controller1(){
            return (request, response) -> {
                response.getWriter().println("hello");
                return null;
            };
        }

    }

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

        @Bean
        public Bean2 bean2(Bean1 bean1) {
            Bean2 bean2 = new Bean2();
            bean2.setBean1(bean1);
            return bean2;
        }
    }

    static class Bean1 {}

    static class Bean2 {
        private Bean1 bean1;

        public void setBean1(Bean1 bean1) {
            this.bean1 = bean1;
        }

        public Bean1 getBean1() {
            return bean1;
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值