原文: http://zetcode.com/springboot/lazybean/

Spring Boot @Lazy教程展示了如何使用 Spring @Lazy注解懒惰地初始化 bean。

Spring 是用于创建企业应用的流行 Java 应用框架。 Spring Boot 是 Spring 框架的演进,可帮助您轻松创建独立的,生产级的基于 Spring 的应用。

@Lazy

@Lazy注解指示是否要延迟初始化 bean。 它可以用于@Component@Bean定义。 @Lazy bean 不会被初始化,直到被另一个 bean 引用或从BeanFactory中显式检索。 不使用@Lazy注解的 Bean 会被初始化。

Spring Boot @Lazy示例

在下面的示例中,我们创建延迟懒惰地初始化的 bean。 它说明了两种类型的 bean 之间的区别。 该应用是一个简单的 Spring Boot Web 应用,可在嵌入式 Tomcat 服务器上运行。 我们使用 Freemarker 模板引擎。

  1. $ tree
  2. .
  3. ├── pom.xml
  4. ├── SpringBootLazy.iml
  5. └── src
  6. ├── main
  7. ├── java
  8. └── com
  9. └── zetcode
  10. ├── Application.java
  11. ├── bean
  12. ├── MyBean.java
  13. ├── MyLazyBean.java
  14. └── StartUpBean.java
  15. └── controller
  16. └── MyController.java
  17. └── resources
  18. ├── application.properties
  19. ├── static
  20. └── index.html
  21. └── templates
  22. └── showMessages.ftl
  23. └── test
  24. └── java

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>SpringBootLazy</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>1.8</maven.compiler.source>
  14. <maven.compiler.target>1.8</maven.compiler.target>
  15. </properties>
  16. <parent>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-parent</artifactId>
  19. <version>1.5.10.RELEASE</version>
  20. </parent>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-freemarker</artifactId>
  25. </dependency>
  26. </dependencies>
  27. <build>
  28. <plugins>
  29. <plugin>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-maven-plugin</artifactId>
  32. </plugin>
  33. </plugins>
  34. </build>
  35. </project>

Spring Boot 启动器是一组方便的依赖项描述符,可以极大地简化 Maven 配置。 spring-boot-starter-parent具有 Spring Boot 应用的一些常用配置。 spring-boot-starter-freemarker是使用 Freemarker 视图构建 MVC Web 应用的入门工具。

spring-boot-maven-plugin提供了 Maven 的 Spring Boot 支持,使我们能够打包可执行的 JAR 或 WAR 档案。 它的spring-boot:run目标运行 Spring Boot 应用。

application.properties

  1. server.port=8086
  2. server.contextPath=/myapp
  3. spring.main.banner-mode=off
  4. logging.level.org.springframework=ERROR

application.properties文件中,我们编写了 Spring Boot 应用的各种配置设置。 完成这些设置后,我们可以通过localhost:8086/myapp/访问该应用。

MyBean.java

  1. package com.zetcode.bean;
  2. import org.springframework.stereotype.Component;
  3. import java.util.logging.Logger;
  4. @Component
  5. public class MyBean {
  6. static Logger log = Logger.getLogger(MyBean.class.getName());
  7. public MyBean() {
  8. log.info("MyBean initialized");
  9. }
  10. public String getMessage() {
  11. return "Message from MyBean";
  12. }
  13. }

这是MyBean。 急切地初始化该 bean,即在 Spring 框架开始时。

MyLazyBean.java

  1. package com.zetcode.bean;
  2. import org.springframework.context.annotation.Lazy;
  3. import org.springframework.stereotype.Component;
  4. import java.util.logging.Logger;
  5. @Component
  6. @Lazy
  7. public class MyLazyBean {
  8. static Logger log = Logger.getLogger(MyLazyBean.class.getName());
  9. public MyLazyBean() {
  10. log.info("MyLazyBean initialized");
  11. }
  12. public String getMessage() {
  13. return "Message from MyLazyBean";
  14. }
  15. }

MyLazyBean包含@Lazy注解。 第一次请求时,它会延迟地初始化。 从控制器请求。

StartUpBean.java

  1. package com.zetcode.bean;
  2. import org.springframework.boot.context.event.ApplicationReadyEvent;
  3. import org.springframework.context.ApplicationListener;
  4. import org.springframework.stereotype.Component;
  5. import java.util.logging.Logger;
  6. @Component
  7. public class StartUpBean implements
  8. ApplicationListener<ApplicationReadyEvent> {
  9. static Logger log = Logger.getLogger(StartUpBean.class.getName());
  10. @Override
  11. public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
  12. log.info("Application is ready");
  13. }
  14. }

StartUpBean实现一个应用监听器; 当应用准备就绪时,它将记录一条消息。

MyController.java

  1. package com.zetcode.controller;
  2. import com.zetcode.bean.MyBean;
  3. import com.zetcode.bean.MyLazyBean;
  4. import org.springframework.beans.factory.BeanFactory;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.ui.Model;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. @Controller
  10. public class MyController {
  11. @Autowired
  12. private BeanFactory factory;
  13. @GetMapping(value="messages")
  14. public String getMessages(Model model) {
  15. MyLazyBean myLazyBean = factory.getBean(MyLazyBean.class);
  16. MyBean myBean = factory.getBean(MyBean.class);
  17. model.addAttribute("mybean", myBean.getMessage());
  18. model.addAttribute("mylazybean", myLazyBean.getMessage());
  19. return "showMessages";
  20. }
  21. }

这是一个控制器类。 它创建两个 bean 并接收它们的消息。 消息显示在 Freemarker 模板中。

  1. @Autowired
  2. private BeanFactory factory;

我们注入BeanFactory。 工厂用于访问 Spring bean。

  1. MyLazyBean myLazyBean = factory.getBean(MyLazyBean.class);

此时,MyLazyBean被初始化。

  1. MyBean myBean = factory.getBean(MyBean.class);

我们从工厂获得了MyBeanMyBean在 Spring 的启动时初始化。

showMessages.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Show data</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <p>
  10. MyBean: ${mybean}
  11. </p>
  12. <p>
  13. MyLazyBean: ${mylazybean}
  14. </p>
  15. </body>
  16. </html>

Freemarker 模板显示来自两个 bean 的消息。

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Home page</title>
  6. </head>
  7. <body>
  8. <a href="messages">Get messages</a>
  9. </body>
  10. </html>

index.html中有一个链接,用于从 Bean 获取消息。

Application.java

  1. package com.zetcode;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Application {
  6. public static void main(String[] args) {
  7. SpringApplication.run(Application.class, args);
  8. }
  9. }

Application设置 Spring Boot 应用。 @SpringBootApplication启用自动配置和组件扫描。

  1. $ mvn spring-boot:run

应用运行后,我们可以导航到localhost:8086/myapp/

  1. Initializing Spring embedded WebApplicationContext
  2. com.zetcode.bean.MyBean : MyBean initialized
  3. com.zetcode.bean.StartUpBean : Application is ready

当 Spring 启动时,我们可以看到这些日志消息。 请注意,MyBean在启动时已初始化。

  1. com.zetcode.bean.MyLazyBean : MyLazyBean initialized

调用控制器时,将初始化MyLazyBean

在本教程中,我们展示了如何使用 Spring @Lazy注解。 您可能也对相关教程感兴趣: