https://howtodoinjava.com/spring5/core/spring-bean-eager-vs-lazy-init/

默认情况下,Spring“应用程序上下文”会在应用程序启动期间主动创建并初始化所有范围为的 Bean。 在大多数情况下,它有助于早期发现 Bean 配置问题。 但是有时,由于项目要求不同,您可能需要标记部分或全部 bean 进行延迟初始化。

Spring 提供了两种简单的方法来配置 bean 的延迟初始化,具体取决于您使用的是哪种配置,即基于 XML 的配置基于 Java 的配置

1. @Lazy初始化的 bean – Java 配置

1.1. 延迟加载特定的 bean

要仅延迟加载特定的 bean,请在 Java 配置中使用@Lazy注解和@Bean注解。

AppConfig.java

  1. import org.springframework.context.annotation.Lazy;
  2. @Configuration
  3. public class AppConfig {
  4. @Lazy
  5. @Bean
  6. public EmployeeManager employeeManager() {
  7. return new EmployeeManagerImpl();
  8. }
  9. }

1.2. 延迟加载所有 bean

要延迟加载所有 bean,请在 Java 配置中使用@Lazy注解以及@Bean注解。

AppConfig.java

  1. import org.springframework.context.annotation.Lazy;
  2. @Lazy
  3. @Configuration
  4. public class AppConfig {
  5. @Bean
  6. public EmployeeManager employeeManager() {
  7. return new EmployeeManagerImpl();
  8. }
  9. }

1.3. @Autowired延迟 Bean

通常,使用@Autowired注解将 bean 注入其他组件。 在这种情况下,我们必须在两个地方都使用惰性标注:

  • 您要延迟加载的 bean 定义
  • 它与@Autowired注解一起注入的位置
  1. @Lazy
  2. @Service
  3. public class EmployeeManagerImpl implements EmployeeManager {
  4. //
  5. }
  1. @Controller
  2. public class EmployeeController {
  3. @Lazy
  4. @Autowired
  5. EmployeeManager employeeManager;
  6. }

在两个地方都没有使用@Lazy注解,它将无法正常工作。

2. XML 配置中的延迟初始化的 bean

2.1. 仅延迟加载特定的 bean

要为特定 bean 启用延迟加载,请在 bean 配置 xml 文件中的 bean 定义上使用lazy-init="true"属性。

beans.xml

  1. <beans>
  2. <bean id="employeeManager" class="com.howtodoinjava.spring.service.impl.EmployeeManagerImpl"
  3. lazy-init="true"/>
  4. <beans>

2.2. 延迟全局加载所有 bean

要为所有 bean 启用延迟加载,请在 bean 配置 xml 文件的beans标签上使用default-lazy-init="true"属性。

beans.xml

  1. <beans default-lazy-init="true">
  2. <bean id="employeeManager" class="com.howtodoinjava.spring.service.impl.EmployeeManagerImpl" />
  3. <beans>

3. Spring 延迟加载演示

让我们看一下 bean 的代码,我们正在尝试延迟加载。

  1. @Lazy
  2. @Service
  3. public class EmployeeManagerImpl implements EmployeeManager {
  4. @Override
  5. public Employee create() {
  6. Employee emp = new Employee();
  7. emp.setId(1);
  8. emp.setName("Lokesh");
  9. return emp;
  10. }
  11. @PostConstruct
  12. public void onInit(){
  13. System.out.println("EmployeeManagerImpl Bean is Created !!");
  14. }
  15. }

我已放置@PostConstruct注解以检测何时创建 bean。

让我们使用 – 初始化应用程序上下文

3.1. 没有延迟加载

  1. import org.springframework.context.ApplicationContext;
  2. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  3. import com.howtodoinjava.spring.model.Employee;
  4. import com.howtodoinjava.spring.service.EmployeeManager;
  5. public class Main
  6. {
  7. public static void main( String[] args )
  8. {
  9. ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
  10. System.out.println("Bean Factory Initialized !!");
  11. EmployeeManager empManager = ctx.getBean(EmployeeManager.class);
  12. Employee emp = empManager.create();
  13. System.out.println(emp);
  14. }
  15. }

程序输出。

Console

  1. EmployeeManagerImpl Bean is Created !!
  2. Bean Factory Initialized !!
  3. Employee [id=1, name=Lokesh]

在这里,在 bean 工厂完全初始化之前,已创建并初始化了第一个 bean。

3.2. 延迟加载

Console

  1. Bean Factory Initialized !!
  2. EmployeeManagerImpl Bean is Created !!
  3. Employee [id=1, name=Lokesh]

启用 bean 延迟加载后,bean 工厂首先进行完全初始化。 稍后,当我们请求EmployeeManager bean 时,然后工厂创建实例并返回它。

请在注解部分中将与的延迟加载和紧急加载之间的差异相关的问题放在 Spring 中。

学习愉快!

下载源码