代理模式
public enum ScopedProxyMode {
DEFAULT, //默认 NO
NO, // 不用代理
INTERFACES, // 用jdk代理 JdkDynamicAopProxy
TARGET_CLASS; //用 Cglib代理 CglibAopProxy 如果被代理的是接口,或者已经是jdk代理过的,还是会使用 JdkDynamicAopProxy
private ScopedProxyMode() {
}
}
@RefreshScope
注解上用了 @Scope(“refresh”) 即scopeName = refresh
/*
** 包含 @Scope("refresh")
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Scope("refresh")
@Documented
public @interface RefreshScope {
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
在spring收集类信息的时候,会判断类上是否有使用 @Scope注解(包括其子注解),我们一起来看看流程。
1、spring收集类信息,转换为BeanDefinition
// <代码1>
//扫包,收集候选BeanDefinition。 这里只展示关键部分代码
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
...
//扫包,收集候选BeanDefinition
Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);
...
/*
** 解析出 当前类是否有 @Scope 注解(包括其子注解),如果有则
** 请看<代码2>
*/
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
...
if (this.checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//根据作用域配置,看看是否使用代理 请看<代码3>
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//加到容器中去
this.registerBeanDefinition(definitionHolder, this.registry);
}
}
}
//<代码2>
//展示关键代码
public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
private final ScopedProxyMode defaultProxyMode;
protected Class<? extends Annotation> scopeAnnotationType = Scope.class;
public AnnotationScopeMetadataResolver() {
//默认的代理类型为不代理
this.defaultProxyMode = ScopedProxyMode.NO;
}
// 上面的<代码1>中 this.scopeMetadataResolver.resolveScopeMetadata(candidate); 调用到这里
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition)definition;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType);
if (attributes != null) {
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = (ScopedProxyMode)attributes.getEnum("proxyMode");
//如果代理类型为DEFAULT 则设置为默认代理类型
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}
}
//<代码3>
public abstract class AnnotationConfigUtils{
//上面的<代码1>中 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); 调用到这里
static BeanDefinitionHolder applyScopedProxyMode(ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
//如果不代理,则原样返回
return definition;
} else {
/*
** ScopedProxyMode.TARGET_CLASS 、ScopedProxyMode.INTERFACES 就去生产代理包装
** ScopedProxyMode.TARGET_CLASS -> proxyTargetClass = true 用 Cglib代理 CglibAopProxy
** ScopedProxyMode.INTERFACES -> proxyTargetClass = false 用jdk代理 JdkDynamicAopProxy
** proxyTargetClass 就是要生成的代理类型
*/
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
}
}
public abstract class ScopedProxyUtils {
// 代理类 beanname 的前缀
private static final String TARGET_NAME_PREFIX = "scopedTarget.";
private static final int TARGET_NAME_PREFIX_LENGTH = "scopedTarget.".length();
public ScopedProxyUtils() {
}
//上面创建代理BeanDefinition 最终调用到这里
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
...
/*
** 重点,用 ScopedProxyFactoryBean 这个FactoryBean去生产代理bean。我们等会在看它
** 它有个字段 proxyTargetClass 默认为 true
*/
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
...
/*
** 重点,proxyTargetClass 为false 则把 ScopedProxyFactoryBean.proxyTargetClass 设为 false
**
*/
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
} else {
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
}
...
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
我们在来看看 ScopedProxyFactoryBean
/*
** 注意,这个类实现了 ProxyConfig (代理配置类)
** FactoryBean 通过 getObject() 获取bean
*/
public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean {
//这个对象就是代理对象去获取真实对象的工具类。前篇有讲
private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
//代理对象
@Nullable
private Object proxy;
public ScopedProxyFactoryBean() {
// proxyTargetClass 默认为 true 用 Cglib代理 CglibAopProxy
this.setProxyTargetClass(true);
}
// 实现了BeanFactoryAware 在类实例化后会调用这个方法
public void setBeanFactory(BeanFactory beanFactory) {
...
ProxyFactory pf = new ProxyFactory();
//复制配置信息到 ProxyFactory 特别是 proxyTargetClass 字段
pf.copyFrom(this);
pf.setTargetSource(this.scopedTargetSource);
Class<?> beanType = beanFactory.getType(this.targetBeanName);
if (beanType == null) {
throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName + "': Target type could not be determined at the time of proxy creation.");
} else {
if (!this.isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {
pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader()));
}
ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));
pf.addInterface(AopInfrastructureBean.class);
// 最终产生的是哪种代理 就看这里了 ProxyFactory
this.proxy = pf.getProxy(cbf.getBeanClassLoader());
}
}
}
// 实现了 FactoryBean 接口,获取代理bean
public Object getObject() {
if (this.proxy == null) {
throw new FactoryBeanNotInitializedException();
} else {
return this.proxy;
}
}
}
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
// createAopProxy 在父类中 ProxyCreatorSupport
return this.createAopProxy().getProxy(classLoader);
}
}
public class ProxyCreatorSupport extends AdvisedSupport {
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
// this.getAopProxyFactory() 得到的是它 DefaultAopProxyFactory
return this.getAopProxyFactory().createAopProxy(this);
}
}
//真正包装代理类的地方
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public DefaultAopProxyFactory() {
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//注意 config.isProxyTargetClass 他是ProxyFactory.copyFrom(this);复制进来的
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
//使用 Cglib 还是有条件的,如果当前被代理的是接口 或者已经用 JdkDynamic 代理了,那么就会继续使用jdk代理
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
}
最终完成了代理包装。
各位大神,小弟能力有限,如有不恰当的地方,请多多提示,感谢!