Spring IOC 容器 refresh() 方法

 更新时间:2026年05月23日 09:33:32   作者:明夜之约  
Spring容器的refresh()方法是其启动的核心入口,由1个标准步骤,完成从配置加载到Bean实例化的全流程,这篇文章给大家介绍Spring IOC 容器 refresh()方法,感兴趣的朋友跟随小编一起看看吧

Spring IOC 容器的 refresh() 方法是容器启动的核心入口,包含 12 个标准步骤,负责完成从配置加载到 Bean 实例化的全流程。

整体流程是什么

refresh() 方法在 AbstractApplicationContext 中定义,采用模板方法模式,确保容器初始化过程线程安全。12 个步骤按顺序执行:

  • 准备阶段‌:prepareRefresh() 记录启动时间、设置活跃标志。
  • 工厂获取‌:obtainFreshBeanFactory() 创建或刷新 BeanFactory。
  • 工厂配置‌:prepareBeanFactory() 设置类加载器、表达式解析器等基础设施。
  • 后置处理‌:postProcessBeanFactory() 留给子类扩展的空实现。
  • 处理器调用‌:invokeBeanFactoryPostProcessors() 执行配置类后置处理器。
  • 处理器注册‌:registerBeanPostProcessors() 注册 Bean 实例化前后拦截器。
  • 消息源初始化‌:initMessageSource() 处理国际化资源。
  • 事件广播器‌:initApplicationEventMulticaster() 建立事件发布机制。
  • 子类扩展‌:onRefresh() 模板方法供 Web 容器等初始化特定功能。
  • 监听器注册‌:registerListeners() 添加应用事件监听器。
  • Bean 初始化‌:finishBeanFactoryInitialization() 实例化所有非懒加载单例。
  • 刷新完成‌:finishRefresh() 发布容器刷新完成事件。‌‌‌

Spring IOC 容器 refresh() 方法的 12 个标准步骤逐行解析

标签:Spring | IOC | refresh | Bean 生命周期

一、问题引入

// 我们每天都在用的 Spring Boot 启动
SpringApplication.run(MyApp.class, args);
// 其底层最终调用的是:
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();  // ← 一切魔法从这里开始

refresh() 方法是 Spring Framework 最核心的方法之一。从配置文件加载、Bean 定义注册到单例预实例化,整个 Spring 容器的生命周期都在这里完成。本文逐行解析 refresh() 的 12 个标准步骤。

二、refresh()方法全貌

// org.springframework.context.support.AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
        // 步骤 1: 准备刷新
        prepareRefresh();
        // 步骤 2: 获取/刷新 BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 步骤 3: 准备 BeanFactory
        prepareBeanFactory(beanFactory);
        try {
            // 步骤 4: 子类扩展的 BeanFactory 后处理
            postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start(
                "spring.context.beans.post-process");
            // 步骤 5: 执行 BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);
            // 步骤 6: 注册 BeanPostProcessor
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            // 步骤 7: 初始化消息源
            initMessageSource();
            // 步骤 8: 初始化事件广播器
            initApplicationEventMulticaster();
            // 步骤 9: 子类扩展的初始化逻辑
            onRefresh();
            // 步骤 10: 注册监听器
            registerListeners();
            // 步骤 11: 实例化所有非延迟单例 Bean
            finishBeanFactoryInitialization(beanFactory);
            // 步骤 12: 完成刷新,发布事件
            finishRefresh();
        }
        // ... 异常处理
    }
}

三、12 步骤逐行解析

步骤 1:prepareRefresh()—— 准备刷新

protected void prepareRefresh() {
    // 记录启动时间
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    // 初始化属性源(如 @PropertySource 指定的配置文件)
    initPropertySources();
    // 验证必需的环境变量是否都存在
    getEnvironment().validateRequiredProperties();
    // 初始化早期应用监听器
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
}

核心职责:环境准备 + 状态切换 + 属性验证。

步骤 2:obtainFreshBeanFactory()—— 获取 BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 子类实现:创建或刷新内部的 BeanFactory
    refreshBeanFactory();
    // 返回 freshly created BeanFactory
    return getBeanFactory();
}

AnnotationConfigApplicationContext 的实现

@Override
protected final void refreshBeanFactory() throws BeansException {
    // 如果有旧的 BeanFactory,销毁所有 Bean 并关闭
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建新的 DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        // 加载 Bean 定义(@Configuration 类解析)
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source", ex);
    }
}

DefaultListableBeanFactory 是 Spring 最核心的 BeanFactory 实现:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
    // Bean 定义的注册表:key=beanName, value=BeanDefinition
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    // 单例 Bean 的缓存池
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    // 按类型索引的 Bean 名称
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
}

步骤 3:prepareBeanFactory()—— 准备 BeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 添加 SpEL 表达式解析器(@Value("${app.name}") 的解析)
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
    // 添加属性编辑器注册器(String → Date 等类型转换)
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    // 添加 BeanPostProcessor:ApplicationContextAwareProcessor
    // 处理 Aware 接口:ApplicationContextAware, EnvironmentAware, ResourceLoaderAware
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 忽略以下依赖接口的自动装配(由 ApplicationContextAwareProcessor 处理)
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    // 注册可解析的依赖类型:注入时自动映射到当前对象
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    // 注册早期后置处理器:检测 ApplicationListener 类型的 Bean
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    // 检测 LoadTimeWeaver(AOP 加载时织入)
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    // 注册默认环境 Bean(如果用户未定义)
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

核心职责:注册内置的 BeanPostProcessor + 配置自动装配规则 + 注册环境 Bean。

步骤 4:postProcessBeanFactory()—— BeanFactory 后处理(子类扩展)

// AbstractApplicationContext 中为空实现,子类可覆盖
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
// AnnotationConfigApplicationContext 的扩展:
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.postProcessBeanFactory(beanFactory);
    // 添加 ConfigurationClassPostProcessor 的回调
    if (this.basePackages != null && this.basePackages.length > 0) {
        // 扫描 @Component 类并注册 Bean 定义
        this.scanner.scan(this.basePackages);
    }
    if (!this.annotatedClasses.isEmpty()) {
        // 注册 @Configuration 类
        this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
}

步骤 5:invokeBeanFactoryPostProcessors()—— 执行 BeanFactory 后置处理器

这是最重要的步骤之一——处理 @Configuration 类、解析 @Bean 方法、处理 @PropertySource/@ComponentScan/@Import

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, 
        getBeanFactoryPostProcessors());
}

处理顺序(严格按优先级):

1. BeanDefinitionRegistryPostProcessor (继承 BeanFactoryPostProcessor)
   └─ ConfigurationClassPostProcessor  ← 最重要!处理 @Configuration
       ├─ 解析 @ComponentScan → 扫描包下的 @Component
       ├─ 解析 @Import → 处理 @EnableAutoConfiguration
       ├─ 解析 @ImportResource → 加载 XML 配置
       ├─ 解析 @Bean → 注册方法返回值为 Bean
       └─ 解析 @PropertySource → 加载属性文件
2. 常规的 BeanFactoryPostProcessor
   └─ PropertySourcesPlaceholderConfigurer  ← 处理 ${...} 占位符

ConfigurationClassPostProcessor 的核心流程:

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 1. 从注册表中找出所有 @Configuration 类
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        for (String beanName : registry.getBeanDefinitionNames()) {
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
            }
        }
        // 2. 解析每个 @Configuration 类
        ConfigurationClassParser parser = new ConfigurationClassParser(...);
        parser.parse(configCandidates);
        // 3. 读取解析结果,注册新的 Bean 定义
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        ConfigurationClassBeanDefinitionReader reader = new ConfigurationClassBeanDefinitionReader(...);
        reader.loadBeanDefinitions(configClasses);
    }
}

步骤 6:registerBeanPostProcessors()—— 注册 Bean 后置处理器

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

注册顺序(按 Ordered/PriorityOrdered 排序):

1. PriorityOrdered 的 BeanPostProcessor
   └─ AutowiredAnnotationBeanPostProcessor  ← 处理 @Autowired
   └─ CommonAnnotationBeanPostProcessor     ← 处理 @PostConstruct, @PreDestroy, @Resource
2. Ordered 的 BeanPostProcessor
3. 普通的 BeanPostProcessor
   └─ AsyncAnnotationBeanPostProcessor     ← 处理 @Async
   └─ ScheduledAnnotationBeanPostProcessor ← 处理 @Scheduled
   └─ TransactionProxyFactoryBean          ← 处理 @Transactional
   └─ AOP 相关的 BeanPostProcessor         ← 处理 @Aspect
4. ApplicationListenerDetector(内部使用)

AutowiredAnnotationBeanPostProcessor 的注入时机:

public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 1. 查找 @Autowired 标注的字段/方法
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        // 2. 执行注入
        metadata.inject(bean, beanName, pvs);
        return pvs;
    }
}

步骤 7:initMessageSource()—— 初始化消息源

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        // 用户自定义了 MessageSource
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
    } else {
        // 使用默认的 DelegatingMessageSource
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}

步骤 8:initApplicationEventMulticaster()—— 初始化事件广播器

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(
            APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    } else {
        // 默认使用 SimpleApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, 
            this.applicationEventMulticaster);
    }
}

步骤 9:onRefresh()—— 子类扩展(创建内嵌 Web 服务器)

// AbstractApplicationContext 中为空实现
protected void onRefresh() throws BeansException {
}
// ServletWebServerApplicationContext 的扩展:
@Override
protected void onRefresh() {
    super.onRefresh();
    try {
        // 创建内嵌 Tomcat/Jetty/Undertow
        createWebServer();
    } catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}
private void createWebServer() {
    WebServer webServer = this.webServer;
    ServletContext servletContext = getServletContext();
    if (webServer == null && servletContext == null) {
        // 从 BeanFactory 获取 WebServerFactory
        ServletWebServerFactory factory = getWebServerFactory();
        // 创建 WebServer(如 TomcatWebServer)
        this.webServer = factory.getWebServer(getSelfInitializer());
    }
}

Spring Boot 内嵌 Tomcat 的创建就是在这里完成的!

步骤 10:registerListeners()—— 注册监听器

protected void registerListeners() {
    // 注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    // 从 BeanFactory 获取所有 ApplicationListener 类型的 Bean
    String[] listenerBeanNames = getBeanFactoryNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    // 发布早期累积的事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

步骤 11:finishBeanFactoryInitialization()—— 实例化所有非延迟单例 Bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 转换服务(String → Integer 等类型转换)
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> 
            getEnvironment().resolvePlaceholders(strVal));
    }
    // 初始化 LoadTimeWeaverAware Bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, 
        false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // 停止使用临时类加载器
    beanFactory.setTempClassLoader(null);
    // 冻结配置(不允许再修改 Bean 定义)
    beanFactory.freezeConfiguration();
    // ★★★ 实例化所有非延迟单例 Bean ★★★
    beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons() 是核心:

@Override
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    // 触发所有非延迟单例 Bean 的实例化
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 非抽象 && 单例 && 非延迟初始化
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                // FactoryBean 特殊处理
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            } else {
                // ★ 普通 Bean 的获取 → 触发创建
                getBean(beanName);
            }
        }
    }
    // 触发 SmartInitializingSingleton 回调
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            ((SmartInitializingSingleton) singletonInstance).afterSingletonsInstantiated();
        }
    }
}

步骤 12:finishRefresh()—— 完成刷新

protected void finishRefresh() {
    // 清除上下文级资源缓存
    clearResourceCaches();
    // 初始化 LifecycleProcessor
    initLifecycleProcessor();
    // 启动所有实现了 Lifecycle 接口的 Bean
    getLifecycleProcessor().onRefresh();
    // ★ 发布 ContextRefreshedEvent 事件 ★
    publishEvent(new ContextRefreshedEvent(this));
    // LiveBeansView MBean 注册(JMX 监控)
    LiveBeansView.registerApplicationContext(this);
}

ContextRefreshedEvent 是应用启动完成的标志,很多框架(如 Dubbo)监听此事件完成服务暴露。

四、12 步骤总结图

┌─────────────────────────────────────────────────────┐
│              refresh() 12 步骤                       │
├─────────────────────────────────────────────────────┤
│ 1. prepareRefresh()           环境准备 + 状态校验     │
│ 2. obtainFreshBeanFactory()   创建 BeanFactory       │
│ 3. prepareBeanFactory()       注册内置 BPP           │
│ 4. postProcessBeanFactory()   子类扩展(扫描)        │
│ 5. invokeBeanFactoryPostProcessors() @Configuration  │
│ 6. registerBeanPostProcessors() 注册 @Autowired/AOP  │
│ 7. initMessageSource()        国际化                 │
│ 8. initApplicationEventMulticaster() 事件广播器      │
│ 9. onRefresh()                子类(创建 WebServer) │
│ 10. registerListeners()       注册 @EventListener    │
│ 11. finishBeanFactoryInitialization() 实例化单例      │
│ 12. finishRefresh()           发布刷新完成事件        │
└─────────────────────────────────────────────────────┘
         ↓
    Application Ready!

到此这篇关于Spring IOC 容器 refresh() 方法的文章就介绍到这了,更多相关Spring IOC 容器 refresh() 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Intellij IDEA中Maven的使用步骤操作

    Intellij IDEA中Maven的使用步骤操作

    本文给大家介绍Intellij IDEA中Maven的使用步骤操作,通过这些步骤你可以在 IDEA 中高效使用 Maven 管理项目依赖、构建和部署,是 Maven 项目的核心配置文件,用于管理依赖和插件,感兴趣的朋友跟随小编一起看看吧
    2025-07-07
  • JAVA面向对象之继承 super入门解析

    JAVA面向对象之继承 super入门解析

    在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么引用里面的父类对象呢?用super来引用,this指当前对象的引用,super是当前对象里面的父对象的引用
    2022-01-01
  • rocketMQ如何避免消息重复消费问题

    rocketMQ如何避免消息重复消费问题

    这篇文章主要介绍了rocketMQ如何避免消息重复消费问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Java使用PreparedStatement接口及ResultSet结果集的方法示例

    Java使用PreparedStatement接口及ResultSet结果集的方法示例

    这篇文章主要介绍了Java使用PreparedStatement接口及ResultSet结果集的方法,结合实例形式分析了PreparedStatement接口及ResultSet结果集的相关使用方法与操作注意事项,需要的朋友可以参考下
    2018-07-07
  • springcloud feign调其他微服务时参数是对象的问题

    springcloud feign调其他微服务时参数是对象的问题

    这篇文章主要介绍了springcloud feign调其他微服务时参数是对象的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java实现读取csv文件的两种方式

    Java实现读取csv文件的两种方式

    这篇文章主要为大家详细介绍了如何利用Java读取csv文件的两种方式,文中的示例代码讲解详细,对大家的学习或工作有一定的帮助,感兴趣的小伙伴可以了解一下
    2023-12-12
  • Dubbo本地调试的几种方式总结

    Dubbo本地调试的几种方式总结

    dubbo服务方启动时需要加载的东西太多,如果跑单元测试把服务开启会浪费不少时间,而且单元测试没法保持服务一直开启的状态,这篇文章主要给大家介绍了关于Dubbo本地调试的几种方式,需要的朋友可以参考下
    2022-11-11
  • Java使用Arthas查看接口方法的执行时间的步骤

    Java使用Arthas查看接口方法的执行时间的步骤

    在日常的开发和运维工作中,经常需要监控接口方法的执行时间,以便排查性能问题或优化代码,Arthas 是一款强大的 Java 诊断工具,可以帮助我们轻松地查看接口方法的执行时间,而无需修改代码或重启应用,本文将详细介绍如何使用 Arthas 来查看接口方法的执行时间
    2025-05-05
  • Spring data jpa @Query update的坑及解决

    Spring data jpa @Query update的坑及解决

    这篇文章主要介绍了Spring data jpa @Query update的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java 关于String字符串原理上的问题

    Java 关于String字符串原理上的问题

    字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串,让我们一起来了解它
    2022-04-04

最新评论