spring-context注解源码系列八——@Iazy
注解说明
Indicates whether a bean is to be lazily initialized.
指定一个Bean是否要延迟加载。
@Lazy注解,除了指定一个Bean是否要延迟加载这个功能以外,它还可以和@Resource配合使用,指定是否需要延迟注入。
属性说明
/**
* 是否需要延迟加载(注入)
*/
boolean value() default true;
使用示例
延迟加载
@Service
@Lazy
public class CustomService {
}
延迟注入
@Service
public class CustomService {
public LazyService lazyService;
public LazyService getLazyService() {
return lazyService;
}
@Resource
@Lazy
public void setLazyService(LazyService lazyService) {
System.out.println(lazyService.getClass().getName());
// 打印 com.example.service.LazyService$$EnhancerBySpringCGLIB$$e2f06416
this.lazyService = lazyService;
}
}
相关源码
延迟加载
AnnotationConfigUtils
/**
* 解析beanDefinition的附加的一些通用注解
*/
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd,
AnnotatedTypeMetadata metadata) {
// 如果存在@Lazy,则将其他对应的数据设置给BeanDefinition的lazyInit
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
......
}
AbstractBeanFactory
@Override
public void preInstantiateSingletons() throws BeansException {
......
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 拿到合并后的beanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//满足非抽象、单例、非懒加载则进入创建bean的流程
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
......
}
}
......
}
延迟注入
CommonAnnotationBeanPostProcessor
/**
* Class representing injection information about an annotated field
* or setter method, supporting the @Resource annotation.
* 支持@Resource注入
*/
private class ResourceElement extends LookupElement {
private final boolean lazyLookup;
public ResourceElement(Member member, AnnotatedElement ae,
@Nullable PropertyDescriptor pd) {
......
// 根据@Lazy设置lazyLookup属性
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
@Override
protected Object getResourceToInject(Object target,
@Nullable String requestingBeanName) {
// 根据是否延迟注入,生成需要注入的类
// 不需要延迟注入则返回原始,否则返回代理类实现延迟注入
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
}