ScopedFactoryBean入门级解析
来源:互联网 发布:2016网络最火的神曲 编辑:程序博客网 时间:2024/06/05 10:15
scopedFactoryBean
根据scope的注解属性,判断是否需要scoped代理
static BeanDefinitionHolder applyScopedProxyMode( ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { // 获取@scope的proxyMode属性 ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode(); // 如果此类不需要代理,默认是不需要的代理的 if (scopedProxyMode.equals(ScopedProxyMode.NO)) { return definition; } // 如果需要cglib代理 boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS); // 返回被代理后的beanDefinition return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass); }
具体实现是 org.springframework.aop.scope.ScopedProxyUtils.createScopedProxy()
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition, BeanDefinitionRegistry registry, boolean proxyTargetClass) { String originalBeanName = definition.getBeanName(); BeanDefinition targetDefinition = definition.getBeanDefinition(); // 生成代理bean的名称,就是在前面加上"scopedTarget"前缀 String targetBeanName = getTargetBeanName(originalBeanName); // Create a scoped proxy definition for the original bean name, // "hiding" the target bean in an internal target definition. // 创建一个scope级别的BeanDefinition RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class); proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName)); proxyDefinition.setOriginatingBeanDefinition(targetDefinition); proxyDefinition.setSource(definition.getSource()); proxyDefinition.setRole(targetDefinition.getRole()); proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName); if (proxyTargetClass) { targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); // ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here. // 不需要在这里明确的设置,因为默认是true } else { proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE); } // Copy autowire settings from original bean definition. // 从源bean定义中拷贝自动装配的配置 proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate()); // 是否按照默认的策略进行装配 proxyDefinition.setPrimary(targetDefinition.isPrimary()); if (targetDefinition instanceof AbstractBeanDefinition) { // 拷贝qualifiers的配置 proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition); } // The target bean should be ignored in favor of the scoped proxy. // 设置源bean在其它bean依赖于它的时候,不被作为一个候选项,因为需要放进去的是一个scoped的代理bean targetDefinition.setAutowireCandidate(false); // 当然也不按照默认的策略填充它 targetDefinition.setPrimary(false); // Register the target bean as separate bean in the factory. // 注册源beandefine registry.registerBeanDefinition(targetBeanName, targetDefinition); // Return the scoped proxy definition as primary bean definition // (potentially an inner bean). // 现在返回替换为代理bean的holder return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases()); }
这是BeanDefine实现完成了
在真正的实例化的时候,这个bean会返回一个特殊的代理,
为什么特殊呢,别的代理都是代理同一个bean,但是这个代理牛逼,只是存一下代理的类的信息,每一次都去beanfactory去取。
如果bean的scope是prototype,当然每一次beanfactory都会创建新的bean
如果bean是单例的,当然返回容器缓存的bean。
他是怎么是实现的呢?
在getObject()的时候,从beanfactory去取。。详细看下面源码 org.springframework.aop.scope.ScopedProxyFactoryBean
会先设置BeanFactory
public void setBeanFactory(BeanFactory beanFactory) { if (!(beanFactory instanceof ConfigurableBeanFactory)) { throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory); } ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory; this.scopedTargetSource.setBeanFactory(beanFactory); ProxyFactory pf = new ProxyFactory(); pf.copyFrom(this); //这个这个代理Bean设置Bean的来源,很重要。这个方法决定了, //每次取target的时候,都会调用beanFactory.getBean,所以scope为prototype的时候,可以正确的每一次都是新的实例 // 因为是SimpleBeanTargetSource 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."); } if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) { pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader())); } // Add an introduction that implements only the methods on ScopedObject. // 构建一个introduction,这个introduction只实现了ScopedObject的所有接口 ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName()); pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject)); // Add the AopInfrastructureBean marker to indicate that the scoped proxy // itself is not subject to auto-proxying! Only its target bean is. //将scopedObject作为通知加入到proxy中,DelegatingIntroductionInterceptor作为通知的拦截器, //实际上是使得所有在proxyBean上调用的'getTargetObject`方法都被代理到了`DefaultScopedObject`中。 //在增加通知的同时会生成DefaultIntroductionAdvisor 作为advisor, pf.addInterface(AopInfrastructureBean.class); this.proxy = pf.getProxy(cbf.getBeanClassLoader()); }
org.springframework.aop.scope.DefaultScopedObject
/** * 就是这里 ,每一次调用被注入实例的时候都从工厂中获取 * @return 根据scope的类型由工厂是否返回新的实例 */ @Override public Object getTargetObject() { return this.beanFactory.getBean(this.targetBeanName); }
阅读全文
0 0
- ScopedFactoryBean入门级解析
- php解析wsdl入门级经典教程
- 入门级的SSM架构搭建解析
- XML解析、JSON解析入门
- Javascript Widget入门解析
- HttpComponents入门解析
- HttpComponents入门解析
- HttpComponents入门解析
- HttpComponents入门解析
- JSON 入门解析
- Python入门解析篇
- HttpComponents入门解析
- HttpComponents入门解析
- HTML5入门轻松解析
- HttpComponents入门解析
- HttpComponents入门解析
- HttpComponents入门解析
- UIStackView入门示例解析
- JRE环境配置中path,Java_home,classpath区别
- Properties
- ES6之SET数据结构
- mysql delimiter的说明
- Windbg定位异常系列
- ScopedFactoryBean入门级解析
- table添加内容
- Emmet的HTML语法(敲代码的快捷方式)
- 文章标题
- 机器学习收藏(持续更新)
- android 多进程操作sp问题
- Java第一课:Hello
- hello world
- Hello word