Spring @Lazy批注用例
Spring框架几乎可以毫不费力地为您解决许多常见的编程问题,但是它的某些功能比其他功能鲜为人知。 在本文中,我们将仔细研究属于该组的@Lazy批注。 阅读了几个示例之后,您应该能够将注释应用于日常开发任务。
1. @懒豆初始化
Spring的默认行为是在应用程序启动时创建所有定义的bean。 如果我们考虑到这样的初始化可能会非常耗时的事实,那么在用户开始负担服务器负担之前执行繁重的操作似乎是合理的。
但是,我们是否真的总是需要将所有应用程序组件加载到内存中? 您可能听说过帕累托原理及其适用于软件开发的事实 。 在识别出较少使用的功能之后, 值得考虑对连接的bean进行延迟初始化,尤其是当它们消耗宝贵的资源时 。
如何使豆子变得懒惰? 根据声明此类bean的方式,有两种选择。 如果声明中使用@Bean注释的@Configuration类,你就必须与@Lazy标注来标记它:
@Configuration
class SomeConfig {@Lazy@BeanLazyResource lazyResource() {return new LazyResource();}}
如果Bean使用组件注释之一,并且由组件扫描过程发现,则@Lazy注释可以直接在Bean类中使用:
@Lazy
@Component
class LazyResource {//...
}
@Lazy也可以直接在@Configuration类上使用。 在这种情况下, 该类中定义的所有@Bean对象都会被延迟初始化。
值得记住的是, 用 @Lazy 标记bean 并不意味着其依赖项也被延迟了初始化。 如果您对懒豆图初始化感兴趣,可以通过以下方法实现:
2. @惰性注入–延迟首次创建bean的时间
在bean定义旁边, @Lazy批注还可用于注入点,例如构造函数,构造函数的参数,字段和setter 。 下面是一个对整个构造函数进行延迟注入的示例( 由于从Spring 4.3开始不再使用@Autowired注释,因此省略了它),这意味着所有定义的依赖项都将受到注释的影响。
@Component
class RootResource {private final ResourceDependency dependency;@LazyRootResource(ResourceDependency dependency) {this.dependency = dependency;}}
无论使用哪种注入方法,在所有情况下都将提供代理对象,而不是引用实际依赖项。
重要的是要理解, 如果一个关系用@Lazy标记,这并不意味着要推迟依赖bean的创建。 如果从属bean没有被@Lazy本身标记,它将由Spring容器急切地创建。 这种行为得出的结论是, 延迟注入应该主要与延迟初始化一起使用 。
让我们考虑一个示例,其中有两个相关的bean。 第一个bean标记有@Lazy :
@Lazy
@Component
class LazyResource {//...
}
急于初始化的另一个bean取决于第一个,但是注入点标记为@Lazy:
@Component
class RootResource {private final LazyResource dependency;@LazyRootResource(LazyResource dependency) {this.dependency = dependency;}void useLazyDependency() {dependency.use();}}
在所描述的方案中,当创建RootResource类的新实例时,其依赖关系未初始化。 LazyResource的新实例是在实际需要时构建的 。 在此示例中,这是第一次调用useLazyDependency()方法的时刻。 通过从RootResource的构造函数中删除@Lazy ,必须在注入之前执行LazyResource Bean的初始化。
3.使用@Lazy注入解决循环依赖
应用程序中的循环依赖关系被认为是一种不良的设计模式,但是,如果您没有看到所面临问题的任何替代解决方案,那么惰性注入可能会派上用场。
一旦您尝试在两个bean之间创建一个循环,Spring将通过类似于以下所示的消息通知您有关此问题的信息:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| peerResource defined in file [...\dolszewski\blog\PeerResource.class]
↑ ↓
| someResource defined in file [...\dolszewski\blog\SomeResource.class]
└─────┘
为了解决这个问题,bean不必被延迟初始化。 @Lazy批注仅在注入点之一上是必需的。 首先将创建一个将其依赖项标记为懒惰的依赖项。
4.渴望的豆与@Lazy(false)
尽管与@Lazy批注的第一个关联是按需创建bean的可能性,但它也可以实现相反的效果-渴望初始化。 当您遇到@Lazy批注并了解其存在时,您很可能没有注意到它实际上可以接受其他布尔值属性,该属性指示是否应进行惰性初始化。
您的第二个想法可能是使用@Lazy(false)实际上是无用的,因为您只需删除注释即可实现相同的效果,对吗? 如果考虑使用Spring的简单默认行为,那是绝对正确的,但是生活并不总是那么简单。
当应用程序的启动确实很慢时,您可以考虑对所有托管bean进行延迟初始化,以改善开发体验。 但是, 有时有bean应该始终进行初始化,即使已使用 @ComponentScan(lazyInit = true) 全局禁用了急切的初始化 。 那就是@Lazy(false)进来的时候。
@Lazy(false)
@Component
class AlwaysEagerResource {//...
}
结论
熟悉@Lazy批注的要求不是很高,因为它仅接受一个属性,并且只能在少数地方使用。 但是,考虑到它的多种用途,值得意识到它的存在。 如果您发现该文章有用,请与您的同事和同事分享。 您知道@Lazy扮演主要角色之一的其他有用技巧吗? 如果您愿意,请立即在评论中添加评论。
翻译自: https://www.javacodegeeks.com/2018/03/spring-lazy-annotation-use-cases.html
Spring @Lazy批注用例相关推荐
- spring @lazy_Spring @Lazy批注用例
spring @lazy Spring框架几乎可以毫不费力地为您解决许多常见的编程问题,但是其某些功能比其他功能鲜为人知. 在本文中,我们将仔细研究属于该组的@Lazy批注. 阅读了几个示例之后,您应 ...
- Spring @Order批注
介绍: Spring @Order注释是在Spring 2.0中首次引入的. 然后,它仅用于定义AspectJ建议中的顺序. 在Spring 4.0的后面,对该注释的实现进行了进一步改进. 从那时起, ...
- Spring @RequestParam批注
介绍: Spring @RequestParam批注可用于在处理程序方法中提取查询参数. 在本快速教程中,我们将学习其用法. 首先让我们展示一个API,该API返回具有给定名字和年龄的用户列表: @R ...
- Spring @Value批注
介绍: Spring @Value批注用于将值注入变量和方法参数. 我们可以读取spring环境变量或系统变量. 它还支持SpEL. 在本快速教程中,我们将探讨如何使用Spring @Value批注. ...
- Spring @Service批注
Spring @Service annotation is a specialization of @Component annotation. Spring Service annotation c ...
- Spring @Autowired批注
Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built o ...
- Spring @Repository批注
Spring @Repository annotation is used to indicate that the class provides the mechanism for storage, ...
- Spring如何解决单例循环依赖
所谓的循环依赖是指,A 依赖 B,B 又依赖 A,它们之间形成了循环依赖.那么spring在自动注入的时候是如何解决这个问题的呢? 答案是:三级缓存,就是三个map,通过提早的暴露对象来解决这个问题. ...
- word使用dot模板以spring word 模板为例
word使用dot模板以spring word 模板为例 觉得有用的话,欢迎一起讨论相互学习~ 首先从spring官网中下载word模板, 这个dot文件不能直接打开,本质是word2000以前的遗留 ...
最新文章
- 使用dd查看磁盘前4个扇区的内容
- x is y python_Python 基础
- Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )
- cjson 对象是json数组型结构体_cJSON创建并解析json结构体 | 学步园
- recovery v1跟recovery v2的区别
- 数学建模 TSP(旅行商问题) Lingo求解
- java sql数组_Sql数组类型解决方案
- 纯css实现给图片加标签
- 从武侠门派的角度去解释域、域树、林的含义(下)
- (65)Vue-cli介绍
- C#中double.tostring()的用法
- app.vue里使用data_在电脑使用讯飞有声,通过python自动化朗读
- 已管理员身份从cmd框进入mysql,及常用的简单操作!
- forEach与map
- java爬虫技术怎么学_java网络爬虫基础学习(四)
- Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
- Python的exec
- 中国最顶尖的黑客,连外国人都想拜他为师
- 数学常识--数学符号常识
- Python+PyQt5实现灭霸响指