@Scope @RefreshScope 代理模式

代理模式

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));
            }
        }
    }
}

最终完成了代理包装。

各位大神,小弟能力有限,如有不恰当的地方,请多多提示,感谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值