Spring源码中涉及到的基本概念详解

Spring源码解读 Spring Framework源码地址:https://github.com/spring-projects/spring-framework 从目录结构可以看出整个Spring框架都遵从模块化设计的思路,总共分为20多个模块,如下图所示: 从上图可以看出: Spring主要分为五个部分: 1、测试模块:主要实现了Spring的Junit等测试框架。 2、Spring核心容器:里面... 阅读详情

Spring简单介绍

可以说spring是目前J2EE架构中最成功的轻量级的J2EE架构,spring发展了很多年了,现在使用已经很广泛了,可以说基本上每一家企业都在使用,包括BAT公司,都在spring架构的基础上做了很多的扩展,这个专题主要记录下spring的一些相关笔记,前段时间看了下spring的容器初始化的过程,发现里面的封装实在是太复杂了,封装了上千个类,如果不理解概念,直接去看源码会直接晕掉,spring最核心的功能就是容器化,它将我们项目中的所有java对象都拉入了容器进行管理,这里要说的是我们普通的java bean对象不一定是Bean 对象,但是Bean对象一定是java bean对象,这个概念要理解清楚,spring中提供的功能实在是太多了,spring源码中将面向接口编程体现的淋漓尽致,其中它将不同职责的功能封装到不同的接口中,如果你的bean工厂继承了它,那么你就应该具有这项功能,所以我们在看spring源码的时候需要把这些接口都要理清楚,那么在后面的源码研究上才不会被绕晕,这个专题主要对spring的容器初始化进行分析,看spring是如何管理我们的bean,如何进行DI的,如何进行AOP代理的,如何扩展spring,spring的设计原则遵循了开闭原则,该封装的职责封装起来,该对外开发的接口,向程序员进行开放,所以我们把spring的源码分析完成过后,一定要达到能够扩展spring,比如像spring boot,mybatis这些都是对spring提供的扩展点进行集成;其中比较重要的扩展点有spring提供的@Import注解进行扩展,BeanFactory的后置处理器,其中aop使用Bean的后置处理器。这些后面都会一一的记录,希望我自己之后也能对spring有很深的理解和能够随意扩展spring。

Bean定义

spring中的Bean定义都有哪几种方式,我这边简单介绍下,spring 的bean定义大概有三种方式:1.xml中定义Bean,使用了2.@Component(@Service,@Controller)3.使用java api的方式,就是通过spring给我们提供的api,通过java api的方式进行定义。但是不管以什么样的方式去定义Bean,最终spring都会解析成BeanDefinition,也就是说你在xml中定义了,那么最终也是解析成一个beanName是xx的BeanDefinition,其他的也一样,用注解的方式也是一样的。

XML定义Bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-2.5.xsd">


   <bean id="user" class="com.spring.entity.User" init-method="init"/>

</beans>

UserBean

public class User {

   public User(){
      System.out.println("create user ");
   }

   public void init(){
      System.out.println("user init method...");
   }
}

public static void main(String[] args) {
   //AnnotationConfigApplicationContext
   ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
   System.out.println(classPathXmlApplicationContext.getBean("user"));
}

输出:
create user 
user init method...
com.spring.entity.User@28eaa59a

@Bean或者@Component

定义一个配置扫描类

@ComponentScan("com.spring")
public class AppConfig {


   @Bean
   public Person person(){
      return new Person();
   }
}

public class Person {

   public Person(){
      System.out.println("create Person ");
   }
}

那么启动spring容器过后就会生成两个Bean,分表为user和person

public static void main(String[] args) {
   //AnnotationConfigApplicationContext
   //ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
   //System.out.println(classPathXmlApplicationContext.getBean("user"));

   AnnotationConfigApplicationContext act = new AnnotationConfigApplicationContext(AppConfig.class);
   System.out.println(act.getBean("user"));
   System.out.println(act.getBean("person"));

}

输出:
create user
user init method…
create Person
com.spring.entity.User@1990a65e
com.spring.entity.Person@64485a47

我们通过debug也可以看到
在这里插入图片描述
可以到单例池里面已经把person和user放入了容器了

java api的方式

public static void main(String[] args) {

   AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
   AnnotatedBeanDefinitionReader r = new AnnotatedBeanDefinitionReader(annotationConfigApplicationContext);
   r.registerBean(Person.class);
   annotationConfigApplicationContext.refresh();
   System.out.println(annotationConfigApplicationContext.getBean("person"));

}

这是一种方式,就是我们的Persion是一个普通的javaBean,然后通过AnnotatedBeanDefinitionReader 读取器也会将它放入spring的容器中,不用通过注解或者xml的方式

public static void main(String[] args) {

   AbstractBeanDefinition ab = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
   ab.setBeanClass(Person.class);
   ab.setInitMethodName("init");
   ab.setScope("prototype");
   DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
   factory.registerBeanDefinition("person",ab);
   System.out.println(factory.getBean("person"));

}

这种方式是根据BeanDefinition的构建器去构建一个BeanDefinition,然后设置我们的bean参数,最终放入了容器中
上面的DefaultListableBeanFactory是spring的默认的bean工厂,这个bean工厂用的功能最全,具有最全的功能,用它还可以自己往容器里面直接注册单例池,比如:

AbstractBeanDefinition ab = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
ab.setBeanClass(Person.class);
ab.setInitMethodName("init");
ab.setScope("prototype");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("person",ab);
factory.registerSingleton("xx",new Person());
System.out.println(factory.getBean("person"));
System.out.println(factory.getBean("xx"));

BeanDefinitionReader

BeanDefinitionRead我这边理解为Bean的读取器,简单来说就是对BeanDefinition的读取,读取的BeanDefinition有我们自定义要加入容器的bean,有spring自己内部的beanDefinition,分为几类,有AnnotatedBeanDefinitionReader、XmlBeanDefinitionReader,其中AnnotatedBeanDefinitionReader是对@注解的Bean进行读取成BeanDefinition,然后加入DefaultListableBeanFactory中,也就是说比如我们定义了一个AppConfig

@ComponentScan("com.spring")
public class AppConfig {


   @Bean
   public Person person(){
      return new Person();
   }
}

它就负责把Appconfig扫描成一个BeanDefinition,为后续扫描@Component注解做准备,也就是将Appconfig扫描成一个BeanDefinition,然后后面refresh方法的时候会读取这个Bean定义,然后解析@ComponentScan路径,将所有的Bean注册到BeanDefinition中,最后注册到单例池中;
XmlBeanDefinitionReader是处理xml中配置的,将其扫描成BeanDefinition;
AnnotatedBeanDefinitionReader
它主要是处理的以注解的方式启动的spring容器的Bean读取器,它主要处理的注解是@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description,但是这个类也可以通过api接口手动注册Bean,比如:

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(factory);

reader.register(Person.class);
System.out.println(factory.getBean(Person.class));

XmlBeanDefinitionReader

XmlBeanDefinitionRead主要是读取中bean,然后解析是BeanDefinition,比如看下面的例子:

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
int beanCont = reader.loadBeanDefinitions("spring.xml");
System.out.println(beanCont);

beancount表示加载了多少个BeanDefinition

ClassPathBeanDefinitionScanner

这个并不是BeanDefinitionReader,但是它的作用和BeanDefinitionReader类似,它可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition。

BeanFactory

BeanFactory是spring中核心所在,spring容器启动的最重要的过程就有将所有的Bean扫描成一个BeanDefinition,
然后将BeanDefinition中是单例的Bean注册到单例池中,如果是原型的,那么在每次getBean的时候再从beandefinitionMap中拿出来给你创建一个新的对象给你使用,使用完了也就被gc了,而单例的bean不一样,单例的每次会从单例池中获取一个唯一的对象,然后进行使用;spring中最最核心的BeanFactory就是DefaultListableBeanFactory,它具备了BeanFactory的所有功能,包括别名的注册、单例bean的直接注册、父子容器的管理、依赖注入的实现、环境信息的获取和配置等等,我们先来看下DefaultListableBeanFactory的继承关系:
在这里插入图片描述
看上图可知,DefaultListableBeanFactory在整个继承关系的最下层,则说明它具有最全的功能,我们先来一个一个的分析每个接口和类的作用,spring为什么写了这么多接口,它把每种职责都分表定义到指定的类或者接口中,所以如果你了解了这些接口和类的含义,那么打开一个这个继承关系,你一看就知道它具有什么功能了,比如说你的类实现了Aliasregistry,那么我不看你的类实现细节,我就知道你这个Bean是具有多个别名的,不仅仅是spring,你自己在设计的时候也差不多是这样,别人看你的类继承关系从宏观的角度就知道你这个类具有哪些功能;
Aliasregistry:支持别名功能,一个名字可以对应多个别名,在spring的核心工厂DefaultListableBeanFactory中是由SimpleAliasRegistry来实现的,实现的原理很简单,所以我们看到SimpleAliasRegistry实现了Aliasregistry,那么SimpleAliasRegistry就具有注册别名的功能;
BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition,通过继承关系可以知道BeanDefinitionRegistry目前只给了DefaultListableBeanFactory使用,它的功能就是对BeanDefinition进行管理,如果你自己定义的Bean工厂,那么你实现了BeanDefinitionRegistry则证明你的工厂具有BeanDefinition的管理功能;
SingletonBeanRegistry:该SingletonBeanRegistry接口表示可以对单例bean进行直接注册,就是我们程序员可以手动进行注册这个bean到单例池中,也就是说继承了SingletonBeanRegistry就具有手动注册bean到单例池中的功能;
ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系
HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能
ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能
FactoryBeanRegistrySupport:支持了FactoryBean的功能
AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配
AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames
ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory
AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能
DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大。

ApplicationContext

在这里插入图片描述
HierarchicalBeanFactory:拥有获取父BeanFactory的功能
ListableBeanFactory:拥有获取beanNames的功能
ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
MessageSource:拥有国际化功能

AnnotationConfigApplicationContext

在这里插入图片描述
ConfigurableApplicationContext:继承了ApplicationContext接口,增加了,添加事件监听器、添加BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能
AbstractApplicationContext:实现了ConfigurableApplicationContext接口
GenericApplicationContext:继承了AbstractApplicationContext,实现了BeanDefinitionRegistry接口,拥有了所有ApplicationContext的功能,并且可以注册BeanDefinition,注意这个类中有一个属性(DefaultListableBeanFactory beanFactory)
AnnotationConfigRegistry:可以单独注册某个为类为BeanDefinition(可以处理该类上的@Configuration注解,已经可以处理@Bean注解),同时可以扫描
AnnotationConfigApplicationContext:继承了GenericApplicationContext,实现了AnnotationConfigRegistry接口,拥有了以上所有的功能.

国际化MessageResource

国际化在实际的项目过程中还是会遇到比较多的情况,比如你的前端是需要根据不同语言进行切换的情况,那么就需要国际化,前端传入不同的语言环境,那么我们后端根据不同的语言取出对应语言的数据也是比较常见的场景;首先我们创建两个Resources文件Messages.properties和Messages_en_US.properties
在这里插入图片描述
然后spring底层为我们进行国际化的时候需要一个单例的Bean MessageResourcce
所以我们还需要将MessageResourcce注册为一个Bean并且交给spring进行管理

@Bean
public MessageSource messageSource(){
   ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
   messageSource.setBasenames("messages");
   return messageSource;
}

然后通过下面的方式就可以取出对应的国际化后的值

AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
c.register(AppConfig.class);
c.refresh();
//Local传入空或者传入null取默认语言的
String test = c.getMessage("test", null, new Locale("en_US"));
System.out.printf("test=%s\n",test);

资源加载

ApplicationContext还拥有资源加载的功能,比如,可以直接利用ApplicationContext获取某个文件的内容


AnnotationConfigApplicationContext c = new 
AnnotationConfigApplicationContext();
c.register(AppConfig.class);
c.refresh();
Resource resource = c.getResource("file://D:\\kfk_zk.tar.gz");
System.out.printf("resource.leng=%d\n",resource.contentLength());

还可以获取多个文件,比如获取某个包下面的class文件

AnnotationConfigApplicationContext c = new
 AnnotationConfigApplicationContext();
c.register(AppConfig.class);
c.refresh();
String test = c.getMessage("test", null, null);
System.out.printf("test=%s\n",test);

Resource[] resources = c.getResources("classpath:com/bml/annoation/*.class");
for (Resource resource : resources) {
   System.out.printf("class %s \n",resource.getFile().getAbsolutePath());

}

获取运行时环境

spring现在不仅仅是提供了一些api给我们操作,也不仅仅是做了容器该做的事情,它还提供了一些额外的功能,比如获取系统环境变量信息,其实我们在平时的开发过程中如果要获取系统环境设置的一些参数是通能过System.getProperty来获取,其实spring底层也是这么做

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(AppConfig.class);
    ac.refresh();
ConfigurableEnvironment environment = ac.getEnvironment();
System.out.println(environment.getSystemEnvironment());
System.out.println(environment.getSystemProperties());

通过这种方式我们还可以获取到运行中自定义设置的参数,比如我们设置了某个参数表示启用某项功能也可以在启动参数中进行设置也就是-D参数,比如我们设置一个-D参数,-DRunFlag=2,通过下面的代码可以得到

System.out.println(environment.getProperty("RunFlag"));

spring给我们提供了一个注解也可以将一些参数加入到环境变量中@PropertySource
我们在resource目录下创建一个user.properties文件,然后在Appcaonfig中添加@PropertySource注解
user.properties文件

name=admin
age=23
@ComponentScan("com.spring")
@PropertySource("classpath:user.properties")
public class AppConfig {


   @Bean
   public Person person(){
      return new Person();
   }
}


public static void main(String[] args) {

      AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();
      ConfigurableEnvironment environment = ac.getEnvironment();
      System.out.printf("name=%s ,age=%s\n", 
      environment.getProperty("name"),environment.getProperty("age"));

   }	

不管你使用-D在启动参数中加入还是使用@PropertySource加入的,我们都可以通过ApplicationContext中来获取,还可以通过spring提供的注解@Value来获取

@Value("${name}")
private String name;

@Value("${RunFlag}")
private String runFlag;

也是一样的能获取到

事件发布

定义事件

@Bean
public ApplicationListener applicationListener() {
   return new ApplicationListener() {
      @Override
      public void onApplicationEvent(ApplicationEvent event) {
         System.out.println("接收到了一个事件");
      }
   };
}

发布事件

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(AppConfig.class);
    ac.refresh();
    ac.publishEvent("aaa");

在这里插入图片描述

源码解析:Spring源码解析笔记(一)基本概念 Spring源码解析笔记(一) 本文由colodoo(纸伞)整理 QQ 425343603 Java学习交流群(717726984) 参考 https://www.bilibili.com/video/BV1dK4y127mH 1-10章节 BeanDefinition BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念。 @ 阅读详情

相关推荐

Spring IoC源码学习:总览

前言 Spring 作为现在最优秀的框架之一,被广泛的应用于 Java 项目中,但是大多数人都只知道如何使用,而不知其中的原理。对大多数人来说可能知道如何使用已经足够了,但是对于想提升自己的人来说,学习 Spring 的源码是一个不错的选择。在过去的几个月里,我利用空闲时间将 IoC 的相关源码学习了一下,按照老习惯准备整理成笔记,以博文的形式记录下来,供自己以后使用,也供其他网友参考。由于涉及...

程序员囧辉 1万+

Spring中核心概念详解(看源码必备)

BeanDefinition Bean的定义,在Spring中,我们可以如何去定义一个Bean? <bean/> @Bean @Component(@Service,@Controller) 还有就是可以通过BeanDefinition 比如,我们可以通过定义一个BeanDefinition对象来表示定义了一个Bean: // 定义了一个BeanDefinition AbstractBeanDefinition beanDefinition = BeanDefiniti..

1 374

spring源代码中文详解版

spring源代码的中文解析,让你更加了解spring内部机制,封装类的重用于重写。

Spring源码深度解析(一):IOC容器概念及类关系详解

前言 IOC容器说简单点,其实就是一个Map<String, Object> singletonObjects,创建IOC容器的时候就往容器中添加<bean名称,bean实例>这样的键值对,需要的时候就去容器中取即可。 由于Spring推荐使用注解的方式来使用IOC容器,并且之后学习SpringBoot也是支持全注解,零XML配置。因此本文将全程使用注解来讲解。 IOC源码中涉及到的容器类比较多,我们可以将他们分成2类,如下图,一个是BeanFactory,另一个是Applicati

欢迎来到Jimmy的博客 1462

Crazyflie 2.1固件刷写与地址配置全攻略:从开箱到连接Crazyswarm

本文详细介绍了Crazyflie 2.1微型无人机的固件刷写、地址配置及与Crazyswarm系统的集成方法。从开箱检查到多机协同飞行,涵盖了硬件准备、固件刷写、无线电地址修改等关键步骤,帮助用户快速实现集群飞行控制。特别针对Crazyswarm系统集成提供了实用配置示例和调试技巧。

weixin_42530458的博客 405

CV领域交叉注意力机制:QKV在图像特征增强中的核心作用解析

本文深入解析了CV领域中交叉注意力机制的核心组件QKV在图像特征增强中的关键作用。通过通俗类比和实战案例,阐述了Q(查询)、K(键)、V(值)如何协同实现动态权重分配,从而在目标检测、图像分割与生成等任务中显著提升模型性能与语义对齐能力。

weixin_29194817的博客 442

Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解

前言 随着Spring IoC:context:component-scan节点解析的结束,obtainFreshBeanFactory方法的解析也告一段落,我们通过5篇文章,完整的介绍了obtainFreshBeanFactory方法。本文将介绍obtainFreshBeanFactory方法之后的另一个重要方法——invokeBeanFactoryPostProcessors。 ...

程序员囧辉 2万+

基于ARDUINIO的5路红外循迹小车

基于ARDUINIO的5路红外循迹小车 新手抄袭了很多大神的代码。这里表示感谢。 #define STOP 0 #define FORWARD 1 #define BACKWARD 2 #define STURNLEFT 3 #define STURNRIGHT 4 #define TURNLEFT 5 #define TURNRIGHT 6 #define TURNRIGHT90 7 #define TURNLEFT90 8 int leftA_PIN = A0; int

weixin_48214416的博客 4382

Spring事务源码详解

文章目录一、事务的使用二、源码分析1. @EnableTransactionManagement2. Spring事务源码分析 一、事务的使用 Spring框架提供了强大的事务管理功能,其中注解方式是一种简便且常用的方式。通过使用注解,可以在方法或类级别上声明事务属性,从而实现对数据库操作的事务管理。以下是一个简单的案例,演示了如何使用Spring的注解方式进行事务管理。 假设有一个简单的银行应用,其中涉及两个业务方法:一个是从一个账户转账到另一个账户,另一个是查询账户余额。首先,我们需要在Spring配

qq_43456605的博客 1674

SoC芯片时钟树优化实战:如何用分段CTS解决DDRPHY与Memory Controller的时序难题

本文深入探讨了SoC芯片时钟树优化中的分段CTS技术,重点解决DDRPHY与Memory Controller之间的时序难题。通过分析多域时钟架构的复杂性,提出三级分段CTS策略,并结合28nm移动SoC实战案例,展示如何通过Guide Buffer插入和本地段重构实现72%的跨域偏差改善。文章还涵盖5nm以下工艺的线阻变异、热梯度效应等特殊考量,为数字IC设计提供时钟树综合的高阶解决方案。

kkk56的博客 906

开关电源EMC整改案例-辐射骚扰

2.4.1 获得原始数据。同样的分析可以应用在差模电流的情况, 唯一不同的是, 两根导线的磁场分布是相反的, 磁 场互相抵消, 由于导线中的电流大小相等, 产生的磁场 H 大小相同, 在互相靠近的情况下, 在磁 环内的两个感应磁场大小相同、方向相反, 因此合成之后的感应磁场 B 几乎为 0,对任意一根导 线而言,相当于是一段“无感导线”,对差模电流不会产生任何抑制作用。众所周知, 共模电感的匝数越多, 感量越大, 按道 理来说对共模干扰电流的抑制也会越强烈,对抗辐射 也越有利,然而事实真的如此吗?

经营范围: CTA、SRRC、CCC、移动、电信、联通入库 3502

Spring IoC源码学习:obtainFreshBeanFactory 详解

前言 上文Spring IoC:ApplicationContext 刷新前的配置介绍了refresh 方法前的环境准备操作,接下来正式进入 refresh方法。prepareRefresh是refresh里的第一个方法,主要是一些准备工作,比较简单的方法,看一下就了解了。接下来是obtainFreshBeanFactory方法,该方法用于获得一个新的 BeanFactory,本...

程序员囧辉 1万+

Python 实现生命游戏及进化模拟完整指南

生命模拟是进化计算的一个特定子集,模拟了自然界中所观察到的自然过程,例如粒子或鸟群的聚集方式。生命模拟只是用来探索和优化问题的模拟形式之一,还有很多其他形式的模拟,可以更好地建模各种过程,但它们都源于康威生命游戏 (Conway’s Game of Life)。在本节中,我们将介绍生命模拟的基本概念,并使用 Python 实现康威生命游戏。

盼小辉丶的博客 7万+

Spring IoC源码学习:finishBeanFactoryInitialization 详解

前言 在介绍了 obtainFreshBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors三个重要方法后,我们终于来到了最后一个重要方法:finishBeanFactoryInitialization。finishBeanFactoryInitialization 是这四个方法中最复杂也是最重要的,是整个...

程序员囧辉 9842

华为OD机试 - 小扇和小船的数字游戏 - 二进制(Python/JS/C/C++ 2024 C卷 200分)

二进制表示:任何数 n 的二进制表示中,要找到下一个有相同数量的1的数,我们需要在最低位的0后面的最低位的1进行操作。右侧交换法则:找到右侧的第一个0,位于第一个1的左边,将这个0变成1(提升这个位),并将这个1变成0(下移这个位)。调整尾部1:为了得到最小的数,将所有低于已交换的1的位重置,使得所有1尽可能靠右。

学Java,找哪吒 1162

FreeRTOS深入教程(任务创建的深入和任务调度机制分析)

本篇文章将带大家深入学习任务的创建和分析任务调度的机制。本篇文章深入的讲解了任务创建的内部实现和任务调度的源代码分析和实现,学习这篇文章有助于更深入的学习FreeRTOS的源码。

m0_49476241的博客 6393

Spring AOP源码学习:基本概念

前言 之前用十几篇文章介绍了SpringIoC的源码,作为与IoC齐名的 AOP自然也不能错过。同样的,接下去将会通过几篇文章来解析Spring AOP的源码。 如何将Spring源码导入 IDEA,请参考:Spring IoC:源码学习总览 注:本文的内容以 AspectJ来进行介绍。 关于 AOP 百度百科:AOP即Aspect Oriented...

程序员囧辉 4710

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring 源码学习系列汇总

Spring 系列的文章目录,后续Spring相关文章都会更新到本文,方便大家查阅。

程序员囧辉 5967

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Spring源码解析(十):spring整合mybatis源码

通过sqlSession获取对应的代理对象代理对象执行sql完成数据库操作// 1.解析XML配置// 2.基于解析好的XML配置创建一个SqlSessionFactory// 3.通过SqlSessionFactory,创建一个SqlSession// 4.获取一个代理对象// 5.调用代理对象的方法System.out.println("代理对象查询结果:" + mapper.selectOne(1));根据@MapperScan注解扫描指定路径下接口。

从基础到源码解析的学习记录 1276

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Spring IoC源码学习:@Autowire 详解

前言 在Spring IoC:createBean 详解(上)中代码块4.5和Spring IoC:createBean详解(下)中代码块1、代码块4的 7.1.1我们遗留了一个解析——@Autowire注解的解析。之所以单独提出来,是因为在我现在接触的项目中,使用 @Autowire注解的比例非常高,可以说基本用过Spring的同学都接触过这个注解,重要性不言而喻。因此,单独拿...

程序员囧辉 8867

编译spring源码步骤详解(一)

distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists #distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip distributionUrl=file\:///C\://SofeFile/gradle-6.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper

weixin_43064364的博客 5158

Spring基本概念

本文是Spring系列文章的一部分。其他相关文章见Spring系列文章导航。 本文整理Spring的基本概念。

H.C. Lee的博客 330

Spring IoC源码学习:parseDefaultElement 详解

前言 接着Spring IoC:obtainFreshBeanFactory详解继续往下解析,本文来到 parseDefaultElement 方法。该方法是解析默认命名空间节点的方法,是加载 bean 定义模块的最核心方法。 正文 首先让我们回到Spring IoC:obtainFreshBeanFactory详解文末的 parseBeanDefinitions方法。 ...

程序员囧辉 6195

Spring源码全面图文详解-Spring的13个重要方法

🚀 Spring核心方法解析:refresh()流程摘要 📌 核心阶段: 1️⃣ 配置加载 → BeanDefinition 2️⃣ 工厂增强 → BeanFactoryPostProcessor 3️⃣ 实例化 → 反射创建对象 4️⃣ 依赖注入 → 属性赋值 5️⃣ 初始化 → Aware接口 + init-method 6️⃣ 后处理 → BeanPostProcessor生成代理 💡 关键点:完整生命周期管理,扩展性强,AOP在此实现

404 Not Found 1276

Spring @AutoConfiguration源码详解

概述前面我们了解了spring框架中的@Configuration配置和@ConfigurationProperties加载外部配置注解的使用。那么在Spring boot项目中,应用上下文又是如何找到那么多配置并加载初始化好的呢?@SpringBootApplicationspring boot项目推荐大家在主类中标注@SpringBootApplication这个注解,我们来看看它的源码:@T...

赵林的博客 4571

spring源码详解

文章目录spring源码详解一、面试题1、什么是Spring框架,Spring框架主要包含哪些模块2、Spring框架的优势3、IOC和DI是什么?二、Spring源码阅读环境搭建1、前期运行环境与工具准备2、下载源码3、导入IDEA4、一些查看源码的快捷键 spring源码详解 一、面试题 1、什么是Spring框架,Spring框架主要包含哪些模块 Spring是一个开源框架,Spring是一个轻量级的Java开发框架。它是为了解决企业级应用开发的复杂性而创建的。框架的主要优势就是其分层架构,分层架

weixin_42789698的博客 911
上一篇: 并发编程之条件队列CyclicBarrier(栅栏)
下一篇: Spring生命周期Bean初始化过程详解
Life  journey
博客等级 码龄17年 1万+粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值