Code Monkey home page Code Monkey logo

blog's People

Contributors

erudev avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

muskanmahajan37

blog's Issues

玩转 MyBatis:深度解析与定制

掘金小册《玩转 MyBatis:深度解析与定制》笔记

1. MyBatis 整体架构

MyBatis整体架构

  • 接口层:SqlSession 是与 MyBatis 交互的核心接口(包括后续整合 Spring Framework 用到的 SqlSessionTemplate);
  • 核心层:SqlSession 执行的方法,底层需要经过配置文件的解析、SQL 解析,以及执行 SQL 时的参数映射、SQL 执行、结果集映射,另外还有穿插其中的扩展插件;
  • 支持层:核心层的功能实现,是基于底层的各个模块,共同协调完成的。

SpringBoot 源码解读与原理分析小册笔记

Spring Boot 入门程序原理概述和包扫描

掘金小册《SpringBoot 源码解读与原理分析》笔记

ch03

  1. @SpringBootApplication 是组合注解;
  2. @ComponScan 默认扫描当前配置类所在包以及包下所有组件,exclude 属性会将主启动类、自动配置类屏蔽掉;
  3. @Configuration 可标注配置类,SpringBootConfiguration 并没有对其做实质性扩展

Spring Boot 自动装配

ch04-ch05

AutoConfigurationPackages.Registrar

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        register(registry, new PackageImport(metadata).getPackageName());
    }

    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImport(metadata));
    }

}

ImportBeanDefinitionRegistrar 用于保存导入的配置类所在的根包

AnnotationMetadata 类的注解元数据,个人理解其实就是对类的包装

AutoConfigurationPackages#register

public static void register(BeanDefinitionRegistry registry, String... packageNames) {
  // 判断 BeanFactory 中是否包含 AutoConfigurationPackages
  if (registry.containsBeanDefinition(BEAN)) {
	  BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
	  ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
          // addBasePackages:添加根包扫描包
	  constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
  }
  else {
	  GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
	  beanDefinition.setBeanClass(BasePackages.class);
	  beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
	  beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	  registry.registerBeanDefinition(BEAN, beanDefinition);
  }
}

小结:

  1. SpringFramework 提供了模式注解、@EnableXXX + @import 的组合手动装配;
  2. @SpringBootApplication 标注的主启动类所在包会被视为扫描包的根包

Java 的 SPI

SPI 全称 Service Provider Interface,是 JDK 内置的一种服务提供发现机制。简单来说,它就是一种动态替换发现的机制。

SPI规定,所有要预先声明的类都应该放在 META-INF/services 中。配置的文件名是接口/抽象类的全限定名,文件内容是抽象类的子类或接口的实现类的全限定类名,如果有多个,借助换行符,一行一个。

SpringFramework的SpringFactoriesLoader

  1. AutoConfigurationImportSelector 配合 SpringFactoriesLoader 可加载 “META-INF/spring.factories” 中配置的 @EnableAutoConfiguration 对应的自动配置类。
    DeferredImportSelector 的执行时机比 ImportSelector 更晚。
    SpringFramework 实现了自己的SPI技术,相比较于Java原生的SPI更灵活。

Spring Boot IOC

Spring Boot 准备 IOC 容器

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        // 设置初始化器
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        // 设置监听器
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
}
  1. SpringApplication 的创建和运行是两个不同的步骤,上面代码是创建。
  2. Spring Boot 会根据当前 classpath 下的类来决定应用类型。
  3. Spring Boot 中两个关键的组件:ApplicationContextInitializerApplicationListener ,分别是初始化器和监听器,它们都在 构建 SpringApplication 时注册。

【至此,SpringApplication 初始化完成,下面会真正启动 SpringApplication】

IOC: 准备运行时环境

code

public ConfigurableApplicationContext run(String... args) {
    // 4.1 创建StopWatch对象
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    // 4.2 创建空的IOC容器,和一组异常报告器
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    // 4.3 配置与awt相关的信息
    configureHeadlessProperty();
    // 4.4 获取SpringApplicationRunListeners,并调用starting方法(回调机制)
    SpringApplicationRunListeners listeners = getRunListeners(args);
    // 【回调】首次启动run方法时立即调用。可用于非常早期的初始化(准备运行时环境之前)。
    listeners.starting();
    try {
        // 将main方法的args参数封装到一个对象中
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        // 4.5 准备运行时环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        //.............
    }

Environment

它是 IOC 容器的运行环境,它包括 Profile 和 Properties 两大部分,它可由一个到几个激活的 Profile 共同配置,它的配置可在应用级 Bean 中获取。

可以这样理解:
Environment

  1. SpringApplication 应用中可以使用 SpringApplicationRunListener 来监听 SpringBoot 应用的启动过程。
  2. 在创建 IOC 容器前,SpringApplication 会准备运行时环境 Environment

IOC 创建、初始化容器

  1. Banner 在初始化运行时环境之后,创建 IOC 容器之前打印;
  2. SpringApplication 会根据前面确定好的应用类型,创建对应的 IOC 容器;
  3. IOC 容器在刷新之前会进行初始化、加载主启动类等预处理工作。

IOC 刷新容器-BeanFactory的预处理

//最终调到AbstractApplicationContext的refresh方法
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 1. 初始化前的预处理
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 2. 获取BeanFactory,加载所有bean的定义信息(未实例化)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 3. BeanFactory的预处理配置
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 4. 准备BeanFactory完成后进行的后置处理
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 5. 执行BeanFactory创建后的后置处理器
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 6. 注册Bean的后置处理器
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7. 初始化MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            // 8. 初始化事件派发器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 9. 子类的多态onRefresh
            onRefresh();

            // Check for listener beans and register them.
            // 10. 注册监听器
            registerListeners();
          
            //到此为止,BeanFactory已创建完成

            // Instantiate all remaining (non-lazy-init) singletons.
            // 11. 初始化所有剩下的单例Bean
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 12. 完成容器的创建工作
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            // 13. 清除缓存
            resetCommonCaches();
        }
    }
}

BeanPostProcessor:Bean 的后置处理器,可以在对象实例化但初始化之前,以及初始化之后进行一些后置处理。
BeanPostProcessor

  1. IOC容器在开始刷新之前有加载 BeanDefinition 的过程。
  2. BeanFactory 的初始化中会注册后置处理器,和自动注入的支持。
  3. BeanPostProcessor 的执行时机是在 Bean 初始化前后执行。

Java 并发实现原理: JDK 源码剖析 (笔记)

ch01 多线程基础

栗子

main() 函数退出后,该线程是否会强制退出?整个线程是否会强制退出?

不会。在t1.start() 前面加一行代码 t1.setDaemon(true)。当 main() 函数退出,线程 t1 会跟着退出,整个进程也会退出

线程被分为两类:守护线程和非守护线程,默认都是非守护线程。 在Java中有一个规定:当所有的非守护线程退出后,整个JVM进程就会退出。例如,垃圾回收线程就是守护线程,它们在后台默默工作,当开发者的所有前台线程(非守护线程)都退出之后,整个JVM进程就退出了。

锁的对象是什么?

class A{
    public void synchronized f1() {...}
    public static void synchronized f2() {...}
}

等价于如下代码:

class A {
    public void f1 () {
        synchronized (this) {...}
    }

    public void f1 () {
        synchronized (A.class) {...}
    }
}

对于非静态函数,锁其实是加在对象 a 上面的;对于静态函数,锁是加在 A.class 上的

锁的本质是什么?

从程序角度来看,锁其实就是一个 "对象":

打个比方,线程就是一个个游客,资源就是一个待参观的房子。这个房子每次只允许进去一个人,而锁就是这个房子的门卫。

  1. 锁对象内部有个标志位 (state 变量),记录自己有没有被某个线程占用(也就是记录当前有没有游客已经进入了房子)。最简单的情况是这个state有0、1两个取值,0表示没有线程占用这个锁,1表示有某个线程占用了这个锁。
  2. 如果这个对象被某个线程占用,它得记录这个线程的thread ID,知道自己是被哪个线程占用了(也就是记录现在是谁在房子里面)。
  3. 这个对象还得维护一个thread id list,记录其他所有阻塞的、等待拿这个锁的线程(也就是记录所有在外边等待的游客)。在当前线程释放锁之后(也就是把state从1改回0),从这个thread idlist里面取一个线程唤醒。

volatile:64 位写入的原子性、内存可见性和禁止重排序

MySQL 是怎么运行的笔记

Chapter 01. 初识 MySQL

  1. MySQL 采用客户端/服务器架构
  2. 客户端与服务器通信的方式
    • TCP/IP;
    • 命名管道或内存;
    • UNIX 域套接字。
  3. 处理查询请求
    • 连接管理:主要负责连接的建立与信息的认证
    • 解析与优化:主要进行查询缓存、语法解析、查询优化
    • 存储引擎:主要负责读取和写入底层表中的数据

Chapter 02. 系统变量

  1. 启动选项可以在命令行中直接指定,或者在配置文件中修改。
  2. 修改系统变量的方式
    • 在服务器启动时添加相应的启动选项修改;
    • SET [GLOBALE|SESSION] 系统变量名 = 值;
    • SET[@@(GLOBAL|SESSION).] 系统变量名 = 值;
  3. 查看的系统变量:SHOW [GLOBAL|SESSION] VARIABLES [LIKE 匹配的模式]; show variables like 'max_conn%'

Chapter 03. 字符集和比较规则

字符集指的是某个字符范围的编码规则
比较规则是指对某个字符集中的字符比较大小的一种规则

MySQL 有 4 个级别的字符集和比较规则

  • 服务器级别
  • 数据库级别
  • 表级别
  • 列级别

MySQL 实战 45 讲笔记

基础架构

MySQL 基础架构

  • 连接器:负责跟客户端建立连接、获取权限、维持和管理连接;
  • 查询缓存:查询请求先访问缓存(key 是查询的语句,value 是查询的结果),命中直接返回。不推荐使用缓存,更新会把缓存清除(关闭缓存:参数 query_cache_type 设置为 DEMAND);
  • 分析器:对 SQL 语句解析,判断 sql 是否正确;
  • 优化器:决定使用哪个索引,多表(join)的时候,决定各表的连接顺序;
  • 执行器:执行语句,先判断用户有无权限,使用表定义的存储引擎。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.