您当前的位置:首页 > 电脑百科 > 程序开发 > 开源程序 > 源码

spring源码解析-IOC容器的基本实现

时间:2022-08-04 10:26:01  来源:  作者:javabus

大纲

  • 容器的基本用法
  • spring启动过程分析(spring生命周期)
  • bean 的生命周期
  • IOC核心类总结
  • 常用扩展点

容器的基本用法

spring 是企业级开发框架, 主要功能有 IOC,AOP,Web,ORM等

spring IOC专门用于管理bean对象, 管理对象的创建,属性注入等

spring AOP 给予动态代理,实现了切面编程,动态实现对象功能扩展

 

spring 与其他框架整合,通过 spring 提供的扩展点,把其他框架的对象交给 spring 管理, 对象交给 spring 管理是想要避免手动创建对象,也可以通过@Autowired 等注解实现属性注入,让我们使用对象起来更加方便

  • spring xml 方式配置示例
//1 xml 方式配置spring  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"    xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 配置spring  bean -->    <bean id="petStore" class="cn.JAVAbus.PetStoreService.class">   </bean></beans>//2  初始化 IOC容器ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");PetStoreService service = context.getBean("petStore", PetStoreService.class);

spring启动过程分析(spring生命周期)

spring生命周期与bean生命周期

  • spring启动过程描述

1 BeanDefinition 解析注册

->多种配置方式配置Bean(xml,注解Component,java config)

->各种配置抽象为Resource资源

->通过BeanDefinitionReader 解析BeanDefinition 注册到 BeanDefinitionRegistry

 

2 PostProcessor 各种处理器注册调用

->获取BeanFactory

->注册和调用BeanFactoryPostProcessor(bean工厂后置处理器)

->注册BeanFactoryPostProcessors

 

3 bean 生命周期处理

->实例化对象

->依赖注入

->bean 初始化

-> 存放到SpringContext容器

  • 以AbstractApplicationContext中的refresh()方法为起点进行源码分析
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {  this(); //创建BeanDefinitionReader,BeanDefinitionScanner对象  //BeanDefinition解析和注册 (DefaultListableBeanFactory.beanDefinitionMap)  register(componentClasses);  refresh();}public void refresh() throws BeansException, IllegalStateException {  synchronized(this.startupShutdownMonitor) {    StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");    //记录容器开始时间startupDate,设置活跃状态为true,设置environment对象    this.prepareRefresh();    //1 创建beanFactory实例对象, 一般是DefaultListableBeanFactory    ConfigurableListableBeanFactory beanFactory = obtAInFreshBeanFactory();    // Prepare the bean factory for use in this context.    prepareBeanFactory(beanFactory);    try {      // 空实现留给子类扩展 Allows post-processing of the bean factory in context subclasses.      postProcessBeanFactory(beanFactory);      StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");      // Invoke factory processors registered as beans in the context.      //2 按照顺序注册BeanFactoryPostProcessors,并且按照顺序调用      invokeBeanFactoryPostProcessors(beanFactory);      // Register bean processors that intercept bean creation.      //3  按照顺序注册BeanPostProcessors      registerBeanPostProcessors(beanFactory);      beanPostProcess.end();      // 注册国际化相关内容 Initialize message source for this context.      initMessageSource();      // 初始化事件广播 Initialize event multicaster for this context.      initApplicationEventMulticaster();      // 空实现留给子类扩展 Initialize other special beans in specific context subclasses.      onRefresh();      // 注册监听器并且广播早期事件 Check for listener beans and register them.      registerListeners();      // Instantiate all remaining (non-lazy-init) singletons.      //4 调用getBean()方法对非延迟加载的bean进行实例化 (最重要,涉及bean生命周期)      finishBeanFactoryInitialization(beanFactory);      // Last step: publish corresponding event.      finishRefresh();    }  }}

spring bean的生命周期

Spring中每个Bean的生命周期如下:

图片来源于网络

  • spring bean 生命周期 (Bean 解析和注册)

实例化 -> 属性赋值 -> 初始化 -> 销毁

实例化 Instantiation

属性赋值 Populate

初始化 Initialization

销毁 Destruction

 

class

->构造器->反射创建对象

-> 依赖注入(@Autowired)

-> 初始化前(@PostConstruct)->初始化(InitializingBean)->初始化后(AOP)

-> 代理对象->bean

  • spring bean生命周期代码入口 finishBeanFactoryInitialization(beanFactory)
//真正逻辑在 AbstractAutowireCapableBeanFactory.doCreateBean()finishBeanFactoryInitialization()DefaultListableBeanFactory#preInstantiateSingletons()getBean(beanName)AbstractBeanFactory.doGetBean()AbstractAutowireCapableBeanFactory#createBean()//1 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //2 对象实例化 AbstractAutowireCapableBeanFactory.doCreateBean() Object beanInstance = doCreateBean(beanName, mbdToUse, args);BeanWrapper instanceWrapper = null;//doCreateBean-1 通过反射创建对象实例 (调用构造器创建对象)instanceWrapper = createBeanInstance(beanName, mbd, args);//doCreateBean-2 给后置BDpost-processors 一个修改 BeanDefinition的机会applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);    //doCreateBean-3 通过提前暴露一个单例工厂方法,从而使得其他 bean 能够引用到该 bean (解决单例 bean循环依赖)addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//doCreateBean-4 DI 依赖注入 (对象属性初始化,各个属性值注入,其中可能注入其他 bean 的属性,这时候会递归初始化依赖 bean)populateBean(beanName, mbd, instanceWrapper);//doCreateBean-5 调用初始化方法,比如 init-methodexposedObject = initializeBean(beanName, exposedObject, mbd);//initializeBean-1 调用 Aware接口实现类invokeAwareMethods(beanName, bean);//initializeBean-2 bean前置处理 beanProcessor.postProcessBeforeInitialization();wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//initializeBean-3 调用初始化方法((InitializingBean) bean).afterPropertiesSet();invokeInitMethods(beanName, wrappedBean, mbd);//initializeBean-4 bean后置处理 beanProcessor.postProcessAfterInitialization()wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);return exposedObject;//3return beanInstance;  //然后回到AbstractBeanFactory.doGetBean(),执行getSingleton(),注册 bean到容器sharedInstance = getSingleton(beanName, () -> {//todo  2.2 创建 单实例bean (ctrl+T)return createBean(beanName, mbd, args);}     
  • spring bean 生命周期核心代码逻辑
// AbstractBeanFactory.doGetBean()protected <T> T doGetBean(final String name, ...) {  // 1 提取对应的 beanName (传入的 name 可能是别名,FactoryBean(name="&aa"))  final String beanName = transformedBeanName(name);  Object bean;  // 2 尝试直接从缓存获取,或者singletonFactories 中的 objectFactory中获取  Object sharedInstance = getSingleton(beanName);  if (sharedInstance != null && args == null) {    //该条件一般为二次获取 bean 才会进入  }else {    //lambda 方式调用 DefaultSingletonBeanRegistry.getSingleton(beanName, ObjectFactory<?>)    //获取createBean()创建的bean对象后,走getSingleton()逻辑添加bean 到bean容器(DefaultSingletonBeanRegistry.singletonObjects    sharedInstance = getSingleton(beanName, () -> {      //todo  2.2 调用createBean()方法创建对象      return createBean(beanName, mbd, args);    }    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  }}//...return (T) bean;}  //AbstractAutowireCapableBeanFactory.doCreateBean()//spring bean 生命周期核心代码逻辑 (bean 实例化,依赖注入,以及初始化)protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args){  // Instantiate the bean. (装饰模式)  BeanWrapper instanceWrapper = null;  if (instanceWrapper == null) {    //todo 1 根据指定的 bean 使用对应的策略来创建 bean,如:工厂方法,构造函数注入,简单初始化    instanceWrapper = createBeanInstance(beanName, mbd, args);  }  // Initialize the bean instance.  try {    //todo 2 DI 依赖注入 (对象属性初始化,各个属性值注入,其中可能注入其他 bean 的属性,这时候会递归初始化依赖 bean)    populateBean(beanName, mbd, instanceWrapper);    //todo 3 调用初始化方法,比如 init-method    exposedObject = initializeBean(beanName, exposedObject, mbd);  }  // ...Register bean as disposable.   return exposedObject;} 

Bean生命周期-常用扩展点

  • 第一大类:容器级生命周期接口方法(影响多个Bean的接口)

容器级生命周期接口方法:包含了
InstantiationAwareBeanPostProcessor和BeanProcessor这两个接口实现,称他们的实现类为“后处理器”。

实现了这些接口的Bean会切入到多个Bean的生命周期中。因此,这些接口的功能非常强大,Spring内部扩展也经常使用这些接口,例如自动注入以及AOP的实现都和他们有关。

 

1 BeanPostProcessor 作用于初始化阶段的前后

2
InstantiationAwareBeanPostProcessor 作用于实例化阶段的前后,

 

这两兄弟可能是Spring扩展中最重要的两个接口!

工厂后处理器接口方法:包含了AspectJWeavingEnabler、
ConfigurationClassPostProcessor、CustomAutowreConfigure等非常有用的工厂后处理器接口的方法,会在应用上下文装配配置文件后立即调用。

  • 第二大类:Bean级别生命周期接口方法(每个 bean调用一次的接口)

1 Aware类型的接口

2 Bean生命周期接口 包含了BeanNameAware、BeanFactoryAware、initialzingBean和DiposableBean这些接口的方法

3 Bean的自身方法: 这个包括了init-method和destory-method方法

 

Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。

基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。

调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!

  • 各个接口调用时机演示
//1 BeanFactoryPostProcessor 工厂后处理器接口@Componentpublic class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {  public CustomBeanFactoryPostProcessor() {    System.out.println("==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor 构造器");  }  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {    System.out.println("==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定义");    //BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person");    //beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);    beanFactory.registerSingleton("newobjr",new Object());  }}// 2 BeanPostProcessor bean处理器  @Componentpublic class CustomBeanPostProcessor implements BeanPostProcessor {  public CustomBeanPostProcessor() {    System.out.println("==[BeanPostProcessor 接口]调用了 CustomBeanPostProcessor 构造器");  }  @Override  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {    System.out.println("==4 [BeanPostProcessor 接口]调用了 "+beanName+".postProcessBeforeInitialization()");    return bean;  }@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  System.out.println("==6 [BeanPostProcessor 接口]调用了 "+beanName+".postProcessAfterInitialization()");  return bean;}}// 3Bean级别生命周期接口方法  @Componentpublic class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {  public Person() {    System.out.println("==1 [Person]调用了构造器,进行对象实例化");  }  @Override  public void setBeanName(String s) {    System.out.println("==2 [BeanNameAware 接口]调用了 BeanNameAware.setBeanName()");  }  @Override  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {    System.out.println("==3 [BeanFactoryAware 接口]调用了 BeanFactoryAware.setBeanFactory()");  }//==4 BeanPostProcessor.postProcessBeforeInitialization()...@PostConstruct//@PostConstruct是一种 BeanPostProcessorpublic void demo() {  System.out.println("==5.1 [@PostConstruct]调用了 Person.demo()");}@Overridepublic void afterPropertiesSet() throws Exception {  System.out.println("==5.2 [InitializingBean 接口]调用了 InitializingBean.afterPropertiesSet()");}//==6 BeanPostProcessor.postProcessAfterInitialization()...@Overridepublic void destroy() throws Exception {  System.out.println("==7 [DisposableBean 接口]调用了 DisposableBean.destroy()");}}  @ComponentScan(basePackages = "spring")public class SpringTest {  public static void main(String[] args) {    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);    System.out.println("spring 容器初始化成功");    Person person1 = context.getBean(Person.class);    //Person person2 = context.getBean(Person.class);    //boolean r = person1 == person2;    //System.out.println("person1 == person2 结果为:" + r); //结果为:false, 在BeanFactoryPostProcessor 中修改了bean scope    context.registerShutdownHook();    System.out.println("main结束");  }}
==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor 构造器==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定义==[BeanPostProcessor 接口]调用了 CustomBeanPostProcessor 构造器==4 [BeanPostProcessor 接口]调用了 springTest.postProcessBeforeInitialization()==6 [BeanPostProcessor 接口]调用了 springTest.postProcessAfterInitialization()//通过以下输出可以观察到person对象,生命周期接口方法调用顺序==1 [Person]调用了构造器,进行对象实例化==2 [BeanNameAware 接口]调用了 BeanNameAware.setBeanName()==3 [BeanFactoryAware 接口]调用了 BeanFactoryAware.setBeanFactory()==4 [BeanPostProcessor 接口]调用了 person.postProcessBeforeInitialization()==5.1 [@PostConstruct]调用了 Person.demo()==5.2 [InitializingBean 接口]调用了 InitializingBean.afterPropertiesSet()==6 [BeanPostProcessor 接口]调用了 person.postProcessAfterInitialization()spring 容器初始化成功person1 == person2 结果为:truemain结束==7 [DisposableBean 接口]调用了 DisposableBean.destroy()

Spring IOC核心类总结

1 BeanDefinition 用于封装 spring bean 的配置信息

2 BeanDefinitionRegistry 用于存放解析后的BeanDefinition对象,spring 提供了扩展机制,允许用户在 spring 框架启动时动态的往BeanDefinitionRegistry容器中注册对象

 

3 BeanFactory 是 Spring 的Bean 工厂,负责 Bean 创建和属性注入(
DefaultListableBeanFactory)

4 BeanFactoryPostProcessor ,BeanFactory的后置处理器; 是 spring 提供的扩展机制;

允许在所有 BeanDefinition配置信息解析完成后,修改 BeanFactory(Bean工厂)信息.例如向BeanDefinitionRegistry注册BeanDefinition对象

在BeanFactory创建完成后会调用BeanFactoryPostProcessor实现类的 postProcessBeanFactory() 方法

 

5
ImportBeanDefinitionRegistrar接口作用于 Spring 解析 Bean 的配置阶段,当解析@Configuration 注解时调用. 需要配合@Import 注解使用

 

6 BeanPostProcessor 是Bean的后置处理器.在 Bean 初始化方法(init-method 属性指定的方法或者 afterPropertiesSet()方法)调用前后,会执行 BeanPostProcessor的拦截逻辑

 

7
ClassPathBeanDefinitionScanner 是BeanDefinition扫描器,能够对象指定包下的 Class 进行扫描,将 Class 转换为BeanDefinition对象注册到BeanDefinitionRegistry 容器中

 

8 FactoryBean 是 Spring 中的工厂 bean,通常用于处理 spring 中配置较为复杂或者由动态代理生成的 Bean 实例.

实现了该接口的 Bean 不能作为普通的 Spring bean 使用而是作为单个对象的工厂.

当通过 Bean 名称获取 FactoryBean 实例时,获取到的并不是FactoryBean对象本身,而是FactoryBean对象 getObject()方法返回的对象

BeanFactory:定义获取bean及bean的各种属性。

HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持。

SingletonBeanRegistry:定义对单例的注册及获取。


DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现。


AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器。


spring IOC 常用类介绍

BeanPostProcessor 注册时机与执行顺序

BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered

 

PriorityOrdered、Ordered接口作为Spring整个框架通用的排序接口,在Spring中应用广泛,也是非常重要的接口。

 

1 PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序

2 Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序

3 都没有实现是三等公民,最后执行

//在以下源码中,可以很清晰的看到Spring注册各种类型BeanPostProcessor的逻辑,//根据实现不同排序接口进行分组。优先级高的先加入,优先级低的后加入。// 首先,加入实现了PriorityOrdered接口的BeanPostProcessors,顺便根据PriorityOrdered排了序String[] postProcessorNames =  beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));    processedBeans.add(ppName);  }}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 然后,加入实现了Ordered接口的BeanPostProcessors,顺便根据Ordered排了序postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {  if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));    processedBeans.add(ppName);  }}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 最后加入其他常规的BeanPostProcessorsboolean reiterate = true;while (reiterate) {  reiterate = false;  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);  for (String ppName : postProcessorNames) {    if (!processedBeans.contains(ppName)) {      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));      processedBeans.add(ppName);      reiterate = true;    }  }  sortPostProcessors(currentRegistryProcessors, beanFactory);  registryProcessors.addAll(currentRegistryProcessors);  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);  currentRegistryProcessors.clear();}//根据排序接口返回值排序,默认升序排序,返回值越低优先级越高。PriorityOrdered、Ordered接口作为Spring整个框架通用的排序接口,在Spring中应用广泛,也是非常重要的接口。

 

 



Tags:IOC容器   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
IoC容器:Spring框架下的开发利器
Spring框架的IoC(InversionofControl)容器是开发Java应用程序的利器之一。它提供了一种灵活的方式来管理对象的创建和依赖关系,使得开发人员能够更加专注于业务逻辑的实现,而不...【详细内容】
2023-11-29  Search: IOC容器  点击:(253)  评论:(0)  加入收藏
Spring中有哪些方式能够把bean注入到ioc容器中?
1. 使用xml的方式来声明Bean的定义,Spring容器在启动的时候会加载并解析这个xml,把bean装载到ioc容器中。2. 使用@ComponentScan注解来扫描声明了@Controller、@Service、@Rep...【详细内容】
2023-11-03  Search: IOC容器  点击:(170)  评论:(0)  加入收藏
.net下优秀的IOC容器框架Autofac的使用方法
Autofac是一个功能强大的依赖注入容器,它提供了一种简单和灵活的方式来管理对象之间的依赖关系。下面是Autofac的一些优点: 简单易用:Autofac提供了一种直观和简洁的方式来注册...【详细内容】
2023-10-20  Search: IOC容器  点击:(47)  评论:(0)  加入收藏
Spring Boot启动了几个IoC容器?如何证明?
2023-03-20  Search: IOC容器  点击:(151)  评论:(0)  加入收藏
spring源码解析-IOC容器的基本实现
大纲 容器的基本用法 spring启动过程分析(spring生命周期) bean 的生命周期 IOC核心类总结 常用扩展点容器的基本用法spring 是企业级开发框架, 主要功能有 IOC,AOP,Web,ORM...【详细内容】
2022-08-04  Search: IOC容器  点击:(374)  评论:(0)  加入收藏
Spring IOC容器对Bean实例化的过程详解源码分析
环境:Spring5.3.3Spring容器启动时,创建 DefaultListableBeanFactory 工厂实例化 AnnotationConfigApplicationContext对象public AnnotationConfigApplicationContext(String...【详细内容】
2021-06-10  Search: IOC容器  点击:(519)  评论:(0)  加入收藏
确定不了解一下Spring两大核心之一的IOC容器嘛
今天菜鸟和大家一起来探讨一下Spring两大核心之一的“IOC”。IOC是什么IOC是“Inversion of Control”的缩写,翻译过来就是“控制反转”。我们先不深究其在Spring中的含义,先...【详细内容】
2021-01-27  Search: IOC容器  点击:(415)  评论:(0)  加入收藏
▌简易百科推荐
全网疯传的前端量子纠缠效果,源码来了!
昨天,很多群里都在疯传一个视频,视频演示了纯前端实现的“量子纠缠”效果,不少前端er表示:“前端白学了”。视频作者昨晚开源一个简化版的实现源码(截止发文,该项目在 Github 上已...【详细内容】
2023-11-24  前端充电宝  微信公众号  Tags:源码   点击:(423)  评论:(0)  加入收藏
深入浅出 OkHttp 源码解析及应用实践
一、MBR分区MBR是Master Boot Record的缩写,是一种旧的分区表格式,用于在硬盘上标识和管理分区。MBR分区表可以标识最多4个主分区或3个主分区和1个扩展分区。2TB的限制是指,使...【详细内容】
2023-05-18  雪竹频道  今日头条  Tags:OkHttp   点击:(347)  评论:(0)  加入收藏
用它就够了!开源的驾驶辅助系统
openpilot介绍openpilot是一个开源的驾驶辅助系统。目前,openpilot 执行自适应巡航控制 (ACC)、自动车道居中 (ALC)、前方碰撞警告 (FCW) 和车道偏离警告 (LDW) 的功能,适用...【详细内容】
2022-11-07  GitHub精选  今日头条  Tags:驾驶辅助   点击:(585)  评论:(0)  加入收藏
七爪源码:使用 NodeJs 观看文件系统
监视文件系统意味着监视特定目录或文件的更改。 有时您可能需要持续观察特定文件或目录的更改。出于这个原因,我们使用像 chokidar 这样的文件系统 Watcher 或内置的 NodeJs...【详细内容】
2022-09-17  庄志炎  今日头条  Tags:NodeJs   点击:(481)  评论:(0)  加入收藏
推荐 5 个开源的 yyds 效率神器
01 Wox:效率神器每次重装系统后,都会重新装一些常用的软件,Wox 这个国产开源免费的软件快捷启动工具是首装的效率工具。在 GitHub 上已经获得了 22k 的 Star。Wox 是一个高效的...【详细内容】
2022-09-16  互联网资讯看板  51CTO  Tags:开源   点击:(415)  评论:(0)  加入收藏
「开源精品」 C# im 聊天通讯架构 FreeIM 支持集群、职责分明、高性能
FreeIM 是什么?FreeIM 使用 websocket 协议实现简易、高性能(单机支持5万+连接)、集群即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已...【详细内容】
2022-09-02  IT狂人日记  今日头条  Tags:FreeIM   点击:(517)  评论:(0)  加入收藏
两款「工作流引擎」快速开发框架源码
推荐两款开源的工作流引擎快速开发框架,该工作流平台轻量简洁、美观快速、可扩展,易学习,能够快速上手进行二次开发。有需要的朋友可以去下载看看。(源码地址在文末)▶ 1:开发环境...【详细内容】
2022-08-23   互联网资讯看板  网易  Tags:框架   点击:(367)  评论:(0)  加入收藏
开源:一款开源的一站式SQL审核查询平台 - Archery
Archey介绍Archery是archer的分支项目,定位于SQL审核查询平台,旨在提升DBA的工作效率,支持多数据库的SQL上线和查询,同时支持丰富的MySQL运维功能,所有功能都兼容手机端操作. 功...【详细内容】
2022-08-10  IT搬砖人    Tags:Archery   点击:(781)  评论:(0)  加入收藏
spring源码解析-IOC容器的基本实现
大纲 容器的基本用法 spring启动过程分析(spring生命周期) bean 的生命周期 IOC核心类总结 常用扩展点容器的基本用法spring 是企业级开发框架, 主要功能有 IOC,AOP,Web,ORM...【详细内容】
2022-08-04  javabus    Tags:IOC容器   点击:(374)  评论:(0)  加入收藏
超低成本!自制linux开发板,全开源
这是一款低成本linux开发板&mdash;&mdash;高性能异构边缘AI视觉开发板。作者参考树莓派A版型,将部分硬件替换。它的成本比树莓派低很多!却不一点比树莓派差!具体介绍如下!我还会...【详细内容】
2022-08-03  嘉立创EDA    Tags:开源   点击:(1083)  评论:(0)  加入收藏
站内最新
站内热门
站内头条