Spring之ScopeMetadata
概述
Spring在注册bean的时候。会通过bean的作用域来决定是否使用代理模式去创建bean。如果是单例模式,那么不会使用代理,非单例就会使用。并且如果这个bean实现了接口,就会使用JDK动态代理,如果继承类,就会使用Cglib代理。
在AnnotatedBeanDefinitionReader方法doRegisterBean中,最后组装BeanDefinitionHolder的时候会决定使用代理方式:
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//这里没有做任何修改,即没有选择代理模式
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
ScopeMetadata
ScopeMetadata部分源码如下:
public class ScopeMetadata {
private String scopeName = BeanDefinition.SCOPE_SINGLETON;
private ScopedProxyMode scopedProxyMode = ScopedProxyMode.NO;
scopeName默认是singleton。这个在ConfigurableBeanFactory中作为属性。prototype就是原型模式。非单例。
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
scopedProxyMode 决定了代理模式使用哪一种方式创建对象。是一个枚举。
ScopedProxyMode
public enum ScopedProxyMode {
DEFAULT,
NO,
INTERFACES,
TARGET_CLASS
}
DEFAULT是默认的。和NO相等。主要是scopeName=singleton的时候使用。非单例模式使用INTERFACES和TARGET_CLASS。TARGET_CLASS是Cglib代理。INTERFACES是JDK动态代理模式。