Spring注解之@Lazy注解,源码分析和总结
一
关于延迟加载的问题,有次和大神讨论他会不会直接或间接影响其他类。spring的好处就是文档都在代码里,网上百度大多是无用功。
不如,直接看源码。所以把当时源码分析的思路丢上来一波。
二 源码分析
/** * Indicates whether a bean is to be lazily initialized. * 用于bean的延迟加载 * <p>May be used on any class directly or indirectly annotated with {@link * org.springframework.stereotype.Component @Component} or on methods annotated with * {@link Bean @Bean}. * 可以用于直接或间接使用的@Component类,或者@Bean方法 * <p>If this annotation is not present on a {@code @Component} or {@code @Bean} definition, * eager initialization will occur. If present and set to {@code true}, the {@code @Bean} or * {@code @Component} will not be initialized until referenced by another bean or explicitly * retrieved from the enclosing {@link org.springframework.beans.factory.BeanFactory * BeanFactory}. If present and set to {@code false}, the bean will be instantiated on * startup by bean factories that perform eager initialization of singletons. * 如果没有此注释则会直接加载。(也就是说启动的时候会按顺序注入spring容器)反之,则会在被另一个bean引用或显式引用前不会被初始化。 * <p>If Lazy is present on a {@link Configuration @Configuration} class, this * indicates that all {@code @Bean} methods within that {@code @Configuration} * should be lazily initialized. If {@code @Lazy} is present and false on a {@code @Bean} * method within a {@code @Lazy}-annotated {@code @Configuration} class, this indicates * overriding the 'default lazy' behavior and that the bean should be eagerly initialized. * 如果@Configuration 上使用了Lazy,则@Configuration 中的所有都会被懒加载。若是没使用,则对项目中的方法进行正常加载,哪怕在其他地方写了Lazy。
* (因为spring默认注入顺序先执行@Configuration ,那么就算后面使用了Lazy实际上也已经在spring容器中了) * <p>In addition to its role for component initialization, this annotation may also be placed * on injection points marked with {@link org.springframework.beans.factory.annotation.Autowired} * or {@link javax.inject.Inject}: In that context, it leads to the creation of a * lazy-resolution proxy for all affected dependencies, as an alternative to using * {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}.
* 除了作用于@Component组件或其@Bean初始化方法,也作用于Inject和Autowired。在这种情况下,它会导致创建一个所有受影响的依赖项的延迟解析代理,作为使用的替代方法
* (就是Autowired注释的bean会默认进行懒加载,除非他之前就被加载了,类似于@Configuration的情况)*/ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Lazy { /** * Whether lazy initialization should occur. */ boolean value() default true;//也就是不用标签是false,用就是true,网上什么@Lazy(true)大多是无谓代码 }
三 总结
就是分两种情况作用于 配置和其相关方法等先加载的 ,作用于 Autowired等后加载的。
特点有两条
先加载的覆盖后加载的。直接的覆盖间接的。
第一条优先于第二条。
就是后加载的间接Bean若是在先加载的配置里被使用了,那么Lazy不起作用。