@lazy注解

174 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

延迟加载模式,通常在我们项目启动加载时间过长的时候,我们会将某些对象加上该注解,等到需要的时间(被另一个 bean引用或从封闭的BeanFactory显式检索)再加载,这样可以很好的缓解启动慢的问题;

如果存在并设置为false, 则bean将在启动时由执行单例初始化的bean工厂实例化 它可用于任何直接或间接使用@Component注释的类或使用@Bean注释的方法;当然也可以放在存在Autowired注解的属性上,它会延迟创建所有受影响的依赖项的解析代理 我们看下doRegisterBean(从给定的bean类注册一个bean,从类声明的注释中派生其元数据。)他这里就有一个判断,存在Lazy.class,就会走abd.setLazyInit(true); 我们再看,ContextAnnotationAutowireCandidateResolver类的isLazy方法,根据描述符获取与包装字段或方法/构造函数参数关联的注释,如果获取到Lazy类且值为true则返回true 毕竟默认是true,如果没,往下看方法,具体看代码,

再看isLazy上面的getLazyResolutionProxyIfNecessary方法,如果是延迟加载调用buildLazyResolutionProxy方法 否则返回null,这就是构建延迟代理;

而对于调用该方法的resolveDependency方法,调用resolveDependency的都是AbstractAutowire、Autowire,Constructor之类的,这样看一切就合理了; 我们看buildLazyResolutionProxy调用的getTarget方法中,是直接调用DefaultListableBeanFactory的doResolveDependency方法来解析依赖,而不是调用更上层的resolveDependency方法来解析依赖,

网上看了这是因为对@Lazy注解的解析就是在resolveDependency方法中完成,如果在这里还是调用resolveDependency方法,那么将会陷入死循环。具体代理对象是使用JDK动态代理或者CGLIB创建出来的代理对象,在调用的时候才会触发调用;