当前位置: 首页 > news >正文

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) {// 刚开始创建好,内部没有任何的beanDefaultListableBeanFactory 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//bean2System.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@55a1c291System.out.println(beanFactory.getBean(Bean1.class).getInter());/*学到了什么a. beanFactory 不会做的事1.不会主动调用BeanFactory后处理器2.不会主动添加Bean后处理器3.不会主动初始化单例4.不会解析beanFactory 还不会解析 ${}与#{}b. bean后处理器会有排序的逻辑*/}@Configurationstatic class Config {@Beanpublic Bean1 bean1() {return new Bean1();}@Beanpublic Bean2 bean2() {return new Bean2();}@Beanpublic Bean3 bean3() {return new Bean3();}@Beanpublic 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()");}@Autowiredprivate 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@23fe1d71testClassPathXmlApplicationContext();testFileSystemXmlApplicationContext();//输出结果为//读取之前...//读取之后...//bean1//bean2DefaultListableBeanFactory 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@7adda9cctestAnnotationConfigurationContext();//        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);}@Configurationstatic class WebConfig {@Beanpublic ServletWebServerFactory servletWebServerFactory() {return new TomcatServletWebServerFactory();}@Beanpublic DispatcherServlet dispatcherServlet(){return new DispatcherServlet();}@Beanpublic DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){return new DispatcherServletRegistrationBean(dispatcherServlet,"/");}@Bean("/hello")public Controller controller1(){return (request, response) -> {response.getWriter().println("hello");return null;};}}@Configurationstatic class Config{@Beanpublic Bean1 bean1() {return new Bean1();}@Beanpublic 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;}}}
http://www.lryc.cn/news/219643.html

相关文章:

  • 云原生|kubernetes |kubelet服务加入系统守护进程supervisor(centos7系统下演示通过)
  • onnx 模型加载部署运行方式
  • 第68讲:MySQL触发器的核心概念以及常见的触发类型应用案例
  • VS Code 开发 Spring Boot 类型的项目
  • 数据中心加密:保障数据安全的重要一环
  • 分享90个节日庆典PPT,总有一款适合您
  • Python Faker批量生成测试数据
  • Docker-compose 运行MySQL 连接不上
  • Educational Codeforces Round 2 D 计算几何
  • hexo博客发布换电脑换地方了怎么办?
  • 最新知识付费变现小程序源码/独立后台知识付费小程序源码/修复登录接口
  • 奥威BI软件 | 职场人的数据可视化救星
  • 最长公共前缀[简单]
  • Java后端开发(十一)-- Mysql8的详细安装与环境配置
  • 什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
  • PyTorch 从tensor.grad 看 backward(权重参数) 和 gradient accumulated
  • fedora 命令行代理proxychains 使用flatpak下载 flathub包
  • 介绍kamailio的dialog模块
  • 性能优于BERT的FLAIR:一篇文章入门Flair模型
  • Weblogic ssrf漏洞复现
  • Memcached构建缓存服务器
  • vue3+element Plus实现弹框的拖拽、可点击底层页面功能
  • Vue+elementui 纯前端实现Excel导入导出功能(区分表头标题)
  • 使用Scrapy的调试工具和日志系统定位并解决爬虫问题
  • Pycharm安装配置Pyqt5教程(保姆级)
  • 基于单片机的养殖场温度控制系统设计
  • 时序分解 | Matlab实现EMD经验模态分解时间序列信号分解
  • 解决无法进入MERCURY路由器管理界面的问题 水星网络路由器
  • Ansible自动化安装部署及使用
  • idea中配置spring boot单项目多端口启动