介绍:
默认情况下, Spring框架在应用程序启动时加载并热切初始化所有bean。 在我们的应用程序中,我们可能有一些非常消耗资源的bean。 我们宁愿根据需要加载此类bean。 我们可以使用Spring @Lazy批注实现此目的 。
在本教程中,我们将学习如何使用@Lazy注释延迟加载我们的bean。
延迟初始化:
如果我们用@Lazy注释标记我们的Spring配置类,那么所有带有@Bean注释的已定义bean将被延迟加载:
 @Configuration  @ComponentScan (basePackages = "com.programmergirl.university" )  @Lazy  public class AppConfig {  @Bean public Student student() { return new Student(); }  @Bean public Teacher teacher() { return new Teacher(); }  } 通过在方法级别使用此注释,我们还可以延迟加载单个bean:
 @Bean  @Lazy  public Teacher teacher() { return new Teacher();  } 测试延迟加载:
让我们通过运行应用程序来快速测试此功能:
 public class SampleApp { private static final Logger LOG = Logger.getLogger(SampleApp. class ); public static void main(String args[]) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig. class );         LOG.info( "Application Context is already up" );  // Beans in our Config class lazily loaded Teacher teacherLazilyLoaded = context.getBean(Teacher. class ); Student studentLazilyLoaded = context.getBean(Student. class ); }  } 在控制台上,我们将看到:
 Bean factory for ...AnnotationConfigApplicationContext:  ...DefaultListableBeanFactory: [...]  ...  Application Context is already up  Inside Teacher Constructor  Inside Student Constructor 显然, Spring在需要时而不是在设置应用程序上下文时初始化了Student和Teacher Bean。
使用
我们还可以在注入点使用@Lazy批注:构造函数,setter或字段级。
假设我们有一个要延迟加载的Classroom类:
 @Component  @Lazy  public class Classroom { public Classroom() { System.out.println( "Inside Classroom Constructor" ); } ...  } 然后通过@Autowired注释将其连接到University bean:
 @Component  public class University {  @Lazy @Autowired private Classroom classroom;  public University() { System.out.println( "Inside University Constructor" ); }  public void useClassroomBean() { this .classroom.getDetails(); ... }  } 在这里,我们懒惰地注入了Classroom bean。 因此,在实例化University对象时,Spring将创建代理Classroom对象并将其映射到该对象。 最后,当我们调用useClassroomBean()时 ,才创建实际的Classroom实例:
 // in our main() method  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();   LOG.info( "Application Context is already up" );   University university = context.getBean(University. class );  LOG.info( "Time to use the actual classroom bean..." );  university.useClassroomBean(); 上面的代码将产生以下日志:
 Bean factory for ...AnnotationConfigApplicationContext: ...DefaultListableBeanFactory: [...] ...  Inside University Constructor  ...  Application Context is already up  Time to use the actual classroom bean...  Inside Classroom Constructor 如我们所见, Classroom对象的实例化被延迟,直到其实际需要为止。
请注意,对于延迟注入,我们必须在组件类以及注入点上都使用@Lazy批注。
结论:
在本快速教程中,我们学习了如何延迟加载Spring Bean。 我们讨论了延迟初始化和延迟注入。
翻译自: https://www.javacodegeeks.com/2019/09/spring-lazy-annotation.html