首页 > 其他分享 >Spring原理基础

Spring原理基础

时间:2024-09-22 11:01:33浏览次数:1  
标签:Spring void 基础 System class 原理 new public out

Spring 高级

1 容器与Bean

1.1 接口容器

1.1.1 BeanFactory是什么

@SpringBootApplication
public class ShowApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);
        /**
         *  1、到底什么是 BeanFactory
         *  - 它是 ApplicationContext 的父接口
         *  - 它才是 Spring 的核心容器,主要的 ApplicationContext 实现 【组合】 了它的功能
         */
        System.out.println(context);

    }

}

1.1.2 BeanFactory作用

@SpringBootApplication
public class ShowApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);
        /**
         BeanFactory 能干点啥
            - 表面上只有 getBean
            - 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供
                - 例子中通过反射查看了它的成员变量 singletonObjects,内部包含了所有的单例 bean
         */
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Map<String,Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
                .forEach(e -> System.out.println(e.getKey() + " = " + e.getValue()));

    }

}

img

1.1.3 applicationContext和BeanFactory比较

@SpringBootApplication
public class ShowApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);

        /**
         * 3、applicationContext 比 BeanFactory 多点啥
                 - ApplicationContext 组合并扩展了 BeanFactory 的功能
        		 - 国际化、通配符方式获取一组 Resource 资源、整合 Environment 环境、事件发布与监听
        		 - 新学一种代码之间解耦途径,事件解耦
         */
        //context.getMessage("hello",null, Locale.CHINA);//国际化
        //classpath* 加一个* 代表去jar包中找
        Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");//资源加载
        for (Resource resource : resources) {
            System.out.println(resource);
        }
        //获取环境变量,不区分大小写
        System.out.println(context.getEnvironment().getProperty("java_home"));
    }

}

img

1.1.4 事件处理

事件处理: 实现组件之间的解耦

UserRegisteredEvent

public class UserRegisteredEvent extends ApplicationEvent {
    //事件,source: 事件源
    public UserRegisteredEvent(Object source) {
        super(source);
    }
}
@SpringBootApplication
public class ShowApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        
        ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);
        context.publishEvent(new UserRegisteredEvent(context));//发送事件
    }

}
@Component
public class Component2 {
    private static final Logger log=   LoggerFactory.getLogger(Component2.class);

    @EventListener
    public void aaa(UserRegisteredEvent event){
        System.out.println(event);
    }
}

img

@Component
public class Component1 {
    private static final Logger log=   LoggerFactory.getLogger(Component1.class);

    @Autowired
    public ApplicationEventPublisher context;
    public void register(){
        log.info("用户注册");
        context.publishEvent(new UserRegisteredEvent(this));
    }
}
@Component
public class Component2 {
    private static final Logger log=   LoggerFactory.getLogger(Component2.class);

    @EventListener
    public void aaa(UserRegisteredEvent event){
        System.out.println(event);
        log.info("发送短信");
    }
}
@SpringBootApplication
public class ShowApplication {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);
        context.getBean(Component1.class).register();
    }
}

img

1.2 容器实现

Spring 的发展历史较为悠久,因此很多资料还在讲解它较旧的实现,这里出于怀旧的原因,把它们都列出来,供大家参考

  • DefaultListableBeanFactory,是 BeanFactory 最重要的实现,像控制反转依赖注入功能,都是它来实现
  • ClassPathXmlApplicationContext,从类路径查找 XML 配置文件,创建容器(旧)
  • FileSystemXmlApplicationContext,从磁盘路径查找 XML 配置文件,创建容器(旧)
  • XmlWebApplicationContext,传统 SSM 整合时,基于 XML 配置文件的容器(旧)
  • AnnotationConfigWebApplicationContext,传统 SSM 整合时,基于 java 配置类的容器(旧)
  • AnnotationConfigApplicationContext,Spring boot 中非 web 环境容器(新)
  • AnnotationConfigServletWebServerApplicationContext,Spring boot 中 servlet web 环境容器(新)
  • AnnotationConfigReactiveWebServerApplicationContext,Spring boot 中 reactive web 环境容器(新)

另外要注意的是,后面这些带有 ApplicationContext 的类都是 ApplicationContext 接口的实现,但它们是组合了 DefaultListableBeanFactory 的功能,并非继承而来

1.2.1 DefaultListableBeanFactory

package com.feng.beanfactory02;

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.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;

public class TestBeanFactory {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //bean 的定义(class,scope,初始化,销毁)
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config",beanDefinition);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }//结果只有config一个,发现 @Configuration 没有生效
        System.out.println("===========================");
        //给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
        System.out.println("===========================");
        //org.springframework.context.annotation.internalConfigurationAnnotationProcessor 让@Configuration生效
        //BeanFactory 后处理器主要功能,补充了一些bean定义
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values()
                .stream().forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
        //当执行到internalConfigurationAnnotationProcessor时,就会解析 @Configuration下的@Bean
        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{
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);
        public Bean1(){
            log.info("构造 Bean1()");
        }
        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2(){
            return bean2;
        }
    }

    static class Bean2{
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);
        public Bean2(){
            log.info("构造 Bean2()");
        }
    }

}

img

img

img

System.out.println("===========================");
//Bean 后处理器,针对bean的生命周期的各个阶段提供扩展,例如@Autowired @Resource ...
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
for (String name : beanFactory.getBeanDefinitionNames()) {
    System.out.println(name);
}
System.out.println(beanFactory.getBean(Bean1.class).getBean2());

img

img

//Bean 后处理器,针对bean的生命周期的各个阶段提供扩展,例如@Autowired @Resource ...
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
for (String name : beanFactory.getBeanDefinitionNames()) {
    System.out.println(name);
}
beanFactory.preInstantiateSingletons();//提前准备好所有的单例(不加这句代码,默认是只会保存类的信息,只有getBean的时候才会创建实例)
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
System.out.println(beanFactory.getBean(Bean1.class).getBean2());
/**
   学到了什么:
    a.beanFactory不会做的事
         1.不会主动调用BeanFactory 后处理器
         2.不会主动添加Bean 后处理器
         3.不会主动初始化单例
         4.不会解析beanFactory 还不会解析 ${} 与 #{}
    b.bean后处理器会有排序的逻辑 (@Autowired排在@Resource前面,所以会先注入)

*/

img

收获

标签:Spring,void,基础,System,class,原理,new,public,out
From: https://www.cnblogs.com/fengpeng123/p/18425053

相关文章

  • springboot+vite 商品管理
    SpringBoot+Vue3+MySql5.7+JDK8一、SpringBoot项目搭建1SpringBoot概述1.1SpringBoot概念SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了......
  • 详解机器学习经典模型(原理及应用)——随机森林
    一、什么是随机森林        随机森林(RandomForest)是一种集成学习方法(EnsembleLearning),它通过构建多个决策树(决策树原理及应用可参考此处)并将它们的结果结合起来,以提高预测的准确性和稳定性(就是多棵树构成一片森林的意思)。与决策树一样,随机森林也是同时可以用于分类......
  • Springboot基于生物技术的智能安全管理系统27766--程序+源码+数据库+调试部署+开发环
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景与意义随着生物技术的飞速发展,其在安全管理领域的应用日益广泛。传统安全管理系统存在身份验证方式单一、易被伪造等弊端,而生物识别技......
  • Springboot基于开源工作流的自来水业扩报装系统2j2yi程序+源码+数据库+调试部署+开发
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统功能:用户,用户申报,方案设计,工程施工,设计院初验,工程公司初验,工程结算,装表通水,用户回访,部门人员,报装任务开题报告内容一、研究背景与意义随着城市......
  • Springboot基于机器学习的高考志愿推荐557bk--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统功能:学生,院校,院校信息,专业信息,高考资讯开题报告内容一、项目背景与意义随着高考竞争的日益激烈,科学合理的志愿填报成为考生和家长关注的焦点。传统的......
  • Shell脚本编程基础(四)
    五种常用文本工具和Crontab调度工具(一)cut:用于从文本中提取特定的字段或列。grep:用于搜索文本中的特定模式。awk:用于处理和分析文本。sed:用于文本替换和编辑。sort:用于对文本行进行排序。CrontabCrontab是用于定时任务调度的工具,可以用来定期执行脚本或命令。......
  • Shell脚本编程基础(一)
    LinuxShell编程入门在Linux系统中,Shell是一个重要的工具,它充当应用程序与计算机内核的交互桥梁。本文将介绍Shell编程的一些基本知识,并通过实例帮助你更好地理解和使用它。什么是Shell?Shell是一种解释型的编程语言,通过解释器将代码翻译成计算机可理解的语言。在......
  • 《AI系统:原理与架构》于华为HC大会2024正式发布
    2024年9月21日,《AI系统:原理与架构》新书发布会在上海世博馆华为HC大会顺利举办。本书由华为昇腾技术专家、B站AI科普博主ZOMI酱和哈工大软件学院副院长苏统华教授联合编写,是领域内AI系统方面填补空白的重磅之作发布会上,《AI系统:原理与架构》的作者、编辑代表分别介绍了相关情况,阐......
  • 右值引用、转移和完美转发(刨析std::move的实现原理)
    文章目录0、类型和值类别1、左值2、右值2.1纯右值2.2将亡值3、左值引用和右值引用左值引用左值引用的特性常量左值引用的特性右值引用4、&&的特性4.1函数重载5、转移和完美转发5.1std::move5.2剖析move的实现std::remove_reference::type5.3forward0......
  • 基于springboot+vue的微信小程序的古代天文知识科普系统设计与实现
    前言......