BeanFactory和Applicationcontext实现

news2024/9/23 17:20:39

1.容器接口

1.BeanFactory能做哪些事

1.什么是beanFactory

  1. 它是spring的核心容器

  2. 是ApplicationContext的父接口

  3. ApplicationContext扩展实现都【组合了】beanFactory

    image-20221219233516234

2.BeanFactory的功能

  1. 明面上只有getBean()方法
  2. 实际上控制反转、依赖注入、bean生命周期的各种功能都是由它的实现类提供

image-20221219235120153

  • 演示一下通过子实现类获取单例bean

      // BeanFactory的子实现类 获取所有单例bean对象
            Field field = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
            // 暴力反射
            field.setAccessible(true);
            BeanFactory beanFactory = context.getBeanFactory();
            Map<String, Object> singletonObjects = (Map<String, Object>) field.get(beanFactory);
            singletonObjects.entrySet().stream().filter(entry -> entry.getKey().startsWith("comentDemo"))
                    .forEach(entry ->
                        System.out.println("key="+entry.getKey()+"-value="+entry.getValue()));
    

    image-20221220000448458

2.ApplicationContext有哪些扩展功能

image-20221224151832892

  • MessageSource:资源国际化功能(具备处理国际化资源的能力,程序支持多种语言,提供一种翻译的能力)

    image-20221224153125279

  • ResourcePatternResolver:根据通配符匹配资源(类路径、磁盘路径)的能力

    image-20221224153949159

  • EnvironmentCapable:获取系统变量和配置变量

      System.out.println(context.getEnvironment().getProperty("server.port"));
    
  • ApplicationEventPublisher:发布事件

      context.publishEvent(new ComentDemo1());
    
       @EventListener
        public void comentDemo(Object event){
            System.out.println("监听到事件"+event);
        }
    

    image-20221224154810996

2.容器实现

1.BeanFactory实现

public class TestBeanFactory {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean的定义
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config", beanDefinition);
        // beanFactory添加后置处理器 (无法获取bean1,bean2 所以需要添加后置处理器处理解析@Configuration和@Bean)
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        // 执行处理器,就能对beanFactory做出扩展
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor ->
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
        // bean后置处理器 针对bean的生命周期的各个阶段提供扩展,例如@Autowired@Resource
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
                .sorted(beanFactory.getDependencyComparator()) // 比较器
                .forEach(beanFactory::addBeanPostProcessor);
        // 打印bean1、bean2
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        beanFactory.preInstantiateSingletons(); // 准备好所有的单例
//        System.out.println(beanFactory.getBean(Bean1.class).getBean2());
        System.out.println(beanFactory.getBean(Bean1.class).getInter());
    }

    @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() {
            System.out.println("bean1 构造器");
        }

        @Autowired
        private Bean2 bean2;

        @Autowired
        @Resource(name = "bean3")   // 到底使用bean3还是bean4? 为什么是bean4呢? 因为Resource后处理器的优先级比Autowired低
        private Inter bean4;

        public Inter getInter() {
            return bean4;
        }

        public Bean2 getBean2() {
            return bean2;
        }

    }

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

2.ApplicationContext实现

public class TestApplication {
    public static void main(String[] args) {
//        testClassPathXmlApplicationContext();
//        testFileSystemApplicationContext();
//        testAnnotationConfigApplicationContext();
        testAnnotationConfigServletWebServerApplicationContext();

/*         classpath或者磁盘实现原理
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        System.out.println("读取之前");
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
        XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(beanFactory);
        definitionReader.loadBeanDefinitions(new ClassPathResource("a02.xml"));
        System.out.println("读取之后");
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);*/
        }


    /**
     * 基于classpath下的xml格式的配置文件来创建
     */
    public static void testClassPathXmlApplicationContext() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("a02.xml");
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }

    /**
     * 基于磁盘路径下的xml格式的配置文件来创建
     */
    public static void testFileSystemApplicationContext() {
        FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/main/resources/a02.xml");
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }

    /**
     * 基于java配置类来创建
     */
    public static void testAnnotationConfigApplicationContext() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }
    /**
     * 基于java配置类来创建,用于web环境
     */
    public static void testAnnotationConfigServletWebServerApplicationContext() {
        AnnotationConfigServletWebServerApplicationContext applicationContext = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
    }

    @Configuration
    static class WebConfig{
        // tomcatweb服务器
        @Bean
        public ServletWebServerFactory servletWebServerFactory(){
            return new TomcatServletWebServerFactory();
        }
        // dispatcherServlet
        @Bean
        public DispatcherServlet dispatcherServlet(){
            return new DispatcherServlet();
        }
        // DispatcherServlet注册到tomcat
        @Bean
        public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet){
            return new DispatcherServletRegistrationBean(dispatcherServlet,"/");
        }

        @Bean("/hello")
        public Controller controller(){
            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;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/132209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tslib-1.4在I.MX6ULL开发板上电容屏不能触摸问题

一、前言 在采用触摸屏的移动终端中&#xff0c;触摸屏性能的调试是个重要问题之一&#xff0c;因为电磁噪声的缘故&#xff0c;触摸屏容易存在点击不准确、有抖动等问题。Tslib是一个开源的程序&#xff0c;能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能&#x…

ESP32-S3 >>> MicroPython 编程初探

今天买了一个ESP32-S3&#xff0c;打算试试在这上面进行MicroPython的编程&#xff08;附资料网址&#xff09;。 首先为了在ESP32上进行mp的编程&#xff0c;需要对其重新烧录固件。这就需要我们电脑安装好CH343驱动&#xff0c;然后找到适用于ESP32-S3的固件&#xff0c;利用…

Diffusion详解及PyTorch代码

首先附上几个大佬的讲解 lilianweng-diffusion-models 这篇博客借鉴了上述博客和视频&#xff0c;同时加上个人的理解整合了一下&#xff0c;整个推导过程非常详细&#xff0c;希望能使每个人都看懂 结合之前讲过的VAE和GAN模型&#xff0c;Diffusion Model和他们的区别就是…

Apache Struts2远程代码执行漏洞(S2-015)复现及修复方案

Apache Struts2远程代码执行漏洞(S2-015)介绍 Apache Struts 2是用于开发JavaEE Web应用程序的开源Web应用框架。Apache Struts 2.0.0至2.3.14.2版本中存在远程命令执行漏洞。远程攻击者可借助带有‘${}’和‘%{}’序列值&#xff08;可导致判断OGNL代码两次&#xff09;的请求…

LabVIEW​​共享​变量生命周期

LabVIEW​​共享​变量生命周期 共享​变量​生命​周期 ​所有​共享​变量​都是​项目​库​的​一部分。​SVE​将会​注册​项目​库​和​库​中​包含​的​共享​变量​&#xff08;当​LabVIEW​需要​调​用​其中​某​个​变量​时&#xff09;​。​默认​情况​…

AlphaGo简易版MuGo源码解析

文章目录前言源码实现MuGo的输入数据模型的搭建模型的训练参考链接结语前言 自从AlphaGo横空出世&#xff0c;战胜李世石后&#xff0c;AI围棋如雨后春笋一般遍地开花。阅读DeepMind的论文有时还是隔靴搔痒&#xff0c;只有钻到代码里&#xff0c;才能一探究竟。于是&#xff…

Arthas诊断追踪性能案例

文章目录1、什么是Arthas2、安装启动3、追踪流程背景&#xff1a;本次案例使用Windows操作系统进行本地环境演示&#xff08;生产环境Linux同理&#xff09; 案例&#xff1a;查询接口性能特别慢&#xff0c;通过Arthas追踪诊断链路中哪个步骤导致性能如此之慢 注意&#xff1a…

code review的思考和实践

使用方式 1.看名称效果图&#xff0c;有没有和自己想要的效果类似的 2.有的话&#xff0c;复制粘贴代码使用 3.也可以自己修改一下 4.css效果并不是特别难&#xff0c;只是有时候我们可能想不到 5.笔者空闲时间&#xff0c;会继续更新的哦&#xff0c;点赞关注不迷路**^_^** …

EMNLP 22:SetGNER: General Named Entity Recognition as Entity Set Generation

SetGNER: General Named Entity Recognition as Entity Set Generation **任务形式&#xff1a;**识别flat、nest和不连续实体。 **任务建模方式&#xff1a;**采用基于pointer的方式实现任务建模&#xff0c;文本序列中的每个word可以用tag表示&#xff0c;具体为&#xff1…

Java算法_LeetCode122:买卖股票的最佳时机II

LeetCode122&#xff1a;买卖股票的最佳时机II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 …

有关于huggingface evaluate的使用

老版本Transformer的from datasets import load_metric&#xff0c;在新版本中被替换成了evaluate。 这个包挺难用的&#xff0c;而且不同版本的接口都有点不太一样&#xff0c;本博客以transformers4.18.0, evaluate0.4.0为例&#xff0c;示范一下如何使用evaluate进行常见的…

【LDF】线性判别函数(一)

基于判别函数的判别准则 对于ccc类分类问题&#xff1a;设 gi(x),i1,2,…,cg_i(\mathbf{x}), i1,2, \ldots, cgi​(x),i1,2,…,c, 表示每个类别对应的判别函数&#xff0c;决策规则为&#xff1a;如果 gi(x)>gj(x),∀j≠ig_i(\mathbf{x})>g_j(\mathbf{x}), \forall j \n…

[机器学习-概念新] 什么是欧式距离、标准化欧式距离、马氏距离、余弦距离

1.欧式距离(Euclidean Distance) 欧式距离源自N维欧氏空间中两点间的距离公式&#xff1a; 代码实践 from scipy import spatial vec1 [1, 2, 3, 4] vec2 [5, 6, 7, 8] euclidean spatial.distance.euclidean(vec1, vec2) print(euclidean) 2.标准化欧式距离&#xff08;S…

狂揽两千星,速度百倍提升,高性能Python编译器Codon开源

这个高性能 Python 编译器具有支持 Python 众多语法、完美互通其他框架等优点。 众所周知&#xff0c;Python 是一门简单易学、具有强大功能的编程语言&#xff0c;在各种用户使用统计榜单中总是名列前茅。相应地&#xff0c;围绕 Python&#xff0c;研究者开发了各种便捷工具&…

G1垃圾回收

目录一、G1垃圾回收器G1垃圾回收阶段&#xff08;3个&#xff09;① Young Collection② Young Collection CM③ Mixed CollectionYoung Collection 跨代引用RemarkG1—垃圾回收器优化字符串去重类卸载巨型对象动态调整阈值一、G1垃圾回收器 定义&#xff1a; Garbage First&…

lanmp环境搭建,你需要一次独立安装来深入了解各个软件

一&#xff0c;安装Apache yum install httpd -y,安装apache,版本为2.4.6&#xff0c;最新为2.4.9。 cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak; vim /etc/httpd/conf/httpd.conf &#xff08;默认唯一&#xff09; 端口改为8000&#xff0c;不能与Ngin…

File类的使用

java&#xff0c;File类File类静态成员变量构造方法常用方法用于创建、删除文件/文件夹的方法用于遍历文件/文件目录的方法文件过滤器方法File类 Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。 File对象代表磁盘…

数据分析的大体思路

目录标题数据分析企业数据的分析的三个方向&#xff1a;离线分析&#xff08;Batch Processing&#xff09;实时分析&#xff08;Real Time Processing |Streaming&#xff09;&#xff1a;机器学习&#xff08;Machine Learning&#xff09;数据分析的流程明确分析的目的和思路…

JVM调优基本概念

1、jvm组成以工作流程 jvm组成 类装载器、运行时数据区&#xff08;内存模型&#xff09;、字节码执行引擎 工作大致流程 首先我们的java类编译成class类文件&#xff0c;当我们的class文件开始执行&#xff0c;我们的虚拟机便开始工作。 类加载器将class加载到运行时数据区…

SSM之Spring(一)

目录 一&#xff1a;Spring简介 1.1 Spring概述 1.2 SpringFrameWork 1.2.1 SpringFrameWork特性 1.2.2 Spring Framework五大功能模块 二&#xff1a;IOC 2.1 IOC容器 2.1.1 IOC思想 2.1.2 IOC容器在Spring中的实现 2.2 基于XML管理bean 2.2.1 入门案例 2.2.2 获取bean…