问题
@Lazy能干什么?
1 |
|
如何使用
可用在类上、方法返回值上、方法上、构造方法上、参数上、以及字段上
类上、方法上、方法返回值上
生成的bean懒加载,只有用到他的时候才会加载1
2// 生成beanDefinition的时候会扫描注解,调用此方法,判断是否有Lazy注解,把beanDefinition的lazy属性变为true。
AnnotationConfigUtils.processCommonDefinitionAnnotations(AnnotatedBeanDefinition, AnnotatedTypeMetadata)构造方法上、参数上、字段上
注入的bean为一个代理过的对象,此方法可以解决循环依赖的问题,以及构造注入循环依赖的问题 源码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {
// 此方法在beanFactory进行ioc调用resolveDependency方法的时候,会调用此代码
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, String beanName){
// 如果是lazy则生成一个代理对象
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
protected boolean isLazy(DependencyDescriptor descriptor) {
// 如果字段上或者方法参数上
for (Annotation ann : descriptor.getAnnotations()) {
Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
if (lazy != null && lazy.value()) {
return true;
}
}
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
Method method = methodParam.getMethod();
// 如果方法为空代表为构造方法
if (method == null || void.class == method.getReturnType()) {
Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
if (lazy != null && lazy.value()) {
return true;
}
}
}
return false;
}
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final String beanName) {
BeanFactory beanFactory = getBeanFactory();
Assert.state(beanFactory instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
// 不管三七二十一,直接生成代理对象,只有在调用bean内部方法的时候才会从beanFactory获取到真正的对象
TargetSource ts = new TargetSource() {
...
};
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
Class<?> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
return pf.getProxy(dlbf.getBeanClassLoader());
}
}
主要作用
- 解决循环注入,构造注入也可以解决
当spring容器不允许循环注入的时候,用@Lazy注入,可以解决。
包括spring.main.allowCircularReferences=false的情况下
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 老曹的私房站!
评论