介绍:
默认情况下, 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