Spring boot enable Lazy Initialization of bean

本文深入探讨了Spring框架中懒加载的实现方式及其对bean初始化的影响。介绍了如何通过配置文件、SpringApplication及@Bean注解来启用或禁用懒加载,以及懒加载在web应用中的具体表现。

概述

  • 当我们启用延迟初始化时,bean 将在需要时初始化,默认情况下在应用程序开始时初始化 bean。
  • 对于 web 应用程序,controller bean 将在该控制器上的第一个 HTTP 请求上进行初始化。
  • @Lazy(false) annotation 注释使用我们可以禁用特定 bean 的延迟。
  • NOTE: 如果在 Bean 初始化时配置错误,那么在应用程序启动时无法识别它,在这种情况下, 应用程序将成功启动,但是当初始化发生时,就会出现错误,只是因为这个原因,默认情况下,spring 延迟初始化为 false。

For example:
DemoController.Java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class DemoController {

    DemoController(){
        System.out.println("Controller init...");
    }
    
    @Autowired
    private EmployeeService employeeService;

    @RequestMapping("/demo")
    public String demo(){
        System.out.println("Preparing HTTP request...");
        return "This is from demo";
    }
}

EmployeeService.Java

import org.springframework.stereotype.Service;

@Service
public class EmployeeService {

    public EmployeeService(){
        System.out.println("Service Init ...");
    }

}

输出:

在第一个请求中,依赖 bean 将被初始化。
wget http://localhost:8181/demo

Controller init...
Service Init ...
Preparing HTTP request...

启用 懒加载


方法一: Enable lazy using application.properties

truevalue 表示懒加载

spring.main.lazy-initialization=true

方法二: Enable lazy using SpringApplication

truevalue 表示懒加载

@SpringBootApplication
public class SpringBootConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication application = new SpringApplication(SpringBootConfig.class);
        application.setLazyInitialization(true);
        application.run();
    }
}

指定bean禁用懒加载

@Service
@Lazy(value = false)                // disable lazy for this bean
public class EmployeeService {

    public EmployeeService(){
        System.out.println("Service Init ...");
    }

}
<think>我们正在处理一个Spring Boot应用启动时出现的Bean创建失败错误。错误信息表明在实例化名为'org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration'的BeanPostProcessor时失败,原因是找不到类com.hikvision.monitor.common.method.MethodInfo。 根据错误信息,我们可以推断: 1. 应用可能引入了Spring Cloud Sleuth相关的依赖,因为错误涉及`SleuthAnnotationAutoConfiguration`。 2. 缺少的类`com.hikvision.monitor.common.method.MethodInfo`属于一个特定的包(可能是公司内部包或第三方库),这个类在类路径中不存在。 解决步骤: 步骤1:检查依赖 首先,确认项目中是否直接或间接引入了Spring Cloud Sleuth。如果是,检查版本是否与其他Spring Cloud组件兼容。同时,检查是否引入了包含`com.hikvision.monitor.common.method.MethodInfo`的依赖。 步骤2:确认缺失的类来源 错误中提到的`com.hikvision.monitor.common.method.MethodInfo`类,看起来像是海康威视(Hikvision)的某个库中的类。如果项目确实需要这个类,那么需要添加相应的依赖。如果项目并不需要这个类,可能是某个依赖错误地引入了它,或者配置错误。 步骤3:排除不需要的依赖或添加缺失的依赖 情况1:如果项目不需要使用海康威视的库,那么可能是某个依赖传递引入了这个类,但实际上这个类并不应该被引入。此时,我们需要找到是哪个依赖引入了这个类,并在构建文件中排除它。 情况2:如果项目确实需要使用这个类,那么我们需要添加包含这个类的依赖。 步骤4:检查项目配置 确保项目的配置文件(如application.properties或application.yml)中没有错误地配置了与海康威视相关的属性,这些属性可能导致Spring尝试初始化相关的Bean。 步骤5:清理和重新构建 在修改依赖后,执行清理和重新构建操作,以确保所有依赖都被正确下载和引入。 具体操作: 1. 查找引入`com.hikvision.monitor`的依赖: 如果使用Maven,可以运行: ```bash mvn dependency:tree ``` 在输出中搜索`com.hikvision`,看是哪个依赖引入了这个包。 如果使用Gradle,可以运行: ```bash gradle dependencies ``` 同样搜索`com.hikvision`。 2. 根据查找结果,决定排除该依赖或添加缺失的依赖。 例如,在Maven中排除依赖: ```xml <dependency> <groupId>some.group</groupId> <artifactId>some-artifact</artifactId> <exclusions> <exclusion> <groupId>com.hikvision</groupId> <artifactId>monitor</artifactId> </exclusion> </exclusions> </dependency> ``` 或者,如果确实需要这个类,则添加依赖: ```xml <dependency> <groupId>com.hikvision</groupId> <artifactId>monitor</artifactId> <version>适当版本</version> </dependency> ``` 3. 如果无法确定依赖的来源,或者排除后仍然有问题,可以考虑检查项目中的类路径配置,确保没有错误的类路径设置。 4. 如果问题仍然存在,检查是否因为版本冲突导致类加载失败。可以尝试统一Spring BootSpring Cloud的版本。 注意:由于错误信息中提到了`SleuthAnnotationAutoConfiguration`,如果项目并不需要Sleuth,可以考虑移除Spring Cloud Sleuth的依赖。 移除Sleuth依赖(如果不需要): 在Maven中,查找并移除: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> ``` 在Gradle中,移除: ```groovy implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' ``` 如果移除后问题解决,则说明问题是由Sleuth配置引起的。如果确实需要使用Sleuth,那么必须解决缺失类的问题。 总结:核心问题是类路径中缺少`com.hikvision.monitor.common.method.MethodInfo`类。我们需要确定这个类是否必要,然后添加依赖或排除导致问题的依赖。 相关问题: 1. 如何排除Maven项目中的传递依赖? 2. Spring Boot应用启动时出现NoClassDefFoundError的常见原因有哪些? 3. 如何统一管理Spring BootSpring Cloud的版本?</think>### Spring Boot应用启动时Bean创建失败错误分析 根据您提供的错误信息,核心问题是:Spring Boot在初始化`SleuthAnnotationAutoConfiguration` Bean时,因缺少`com.hikvision.monitor.common.method.MethodInfo`类导致`NoClassDefFoundError`。以下是系统分析及解决方案: #### 错误原因分析 1. **依赖缺失**(主因): - 应用依赖`spring-cloud-starter-sleuth`但缺少其内部依赖的Hikvision相关类 - 类路径中缺少`com.hikvision.monitor.common.method.MethodInfo`的JAR包 2. **版本冲突**: - Spring BootSpring Cloud Sleuth和Hikvision SDK版本可能存在兼容性问题 - 依赖传递导致引入了不兼容的子依赖 3. **自动配置失败**: `SleuthAnnotationAutoConfiguration`作为BeanPostProcessor在初始化阶段需要完整类路径支持[^1] #### 解决步骤 **第一步:添加缺失依赖** 在`pom.xml`中添加Hikvision SDK依赖(根据实际版本调整): ```xml <dependency> <groupId>com.hikvision</groupId> <artifactId>hikvision-sdk</artifactId> <version>5.1.6</version> <!-- 使用实际版本 --> </dependency> ``` **第二步:排除冲突依赖** 在Sleuth依赖中排除问题模块: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <exclusions> <exclusion> <groupId>com.hikvision.monitor</groupId> <artifactId>problem-module</artifactId> <!-- 替换实际模块名 --> </exclusion> </exclusions> </dependency> ``` **第三步:清理并重建项目** ```bash mvn clean install -U # Maven ./gradlew clean build --refresh-dependencies # Gradle ``` **第四步:验证类路径** 在启动类中添加检查: ```java public static void main(String[] args) { try { Class.forName("com.hikvision.monitor.common.method.MethodInfo"); SpringApplication.run(Application.class, args); } catch (ClassNotFoundException e) { System.err.println("Hikvision类缺失: " + e.getMessage()); } } ``` #### 预防措施 1. **依赖树分析**: ```bash mvn dependency:tree -Dincludes=com.hikvision ``` 2. **版本对齐**: 在`pom.xml`中统一管理版本: ```xml <properties> <spring-cloud.version>2021.0.3</spring-cloud.version> <hikvision.version>5.1.6</hikvision.version> </properties> ``` 3. **启用类加载诊断**: 在`application.properties`中添加: ```properties spring.devtools.restart.enable=true spring.main.lazy-initialization=true ``` > **关键提示**:若问题仍存,检查是否为**企业私有依赖**。若SDK仅在内部仓库提供,需在`pom.xml`中配置私有仓库地址[^2]。 ### 相关问题 1. 如何排查Spring Boot启动时的`NoClassDefFoundError`错误? 2. Spring Cloud Sleuth与第三方SDK集成时有哪些常见兼容性问题? 3. 企业私有依赖在Maven项目中如何正确配置? 4. BeanPostProcessor初始化失败的根本原因有哪些?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值