Spring 自定义Scope

1. 创建一个实现Scope接口的类

  • 实现同一线程使用同一个bean,不同线程创建新的bean

在这里插入图片描述

package org.example.scope;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class CustomScope implements Scope {
    private ThreadLocal local = new ThreadLocal();
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        if (local.get() != null) {
            return local.get();
        }else {
            //调用createBean方法创建一个新的实例
            Object object = objectFactory.getObject();
            local.set(object);
            return object;
        }
    }

    @Override
    public Object remove(String name) {
        return null;
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {

    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }

    @Override
    public String getConversationId() {
        return null;
    }
}

2. 创建一个实现BeanFactoryPostProcessor接口的类

  • 将自定义的scope注册到容器中

在这里插入图片描述

3. 创建一个Scope类型的类

  • 设置scope为fisherScope

在这里插入图片描述

package org.example.scope;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("fisherScope")
public class CustomScopeBean {
}

4. 测试方法

  • 同一线程打印获取2次bean,打印查看hashcode是否一致
  • 不同线程,查看hashcode是否不同

在这里插入图片描述
在这里插入图片描述

5. 源码分析

  • 自定义scope的bean在doGetBean()内的实现方法

在这里插入图片描述

// 1.拿到scope名称,这里是fisherScope
String scopeName = mbd.getScope();
// 2.通过fisherScope拿到CustomScope类
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
	throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
	// 3. 调用自己重写的get方法,如果是新的线程就是调到createBean()创建一个新的实例
	// 如果是同一个线程,先从当前线程的ThreadLocal中拿实例,没有再去调createBean()
	Object scopedInstance = scope.get(beanName, () -> {
		beforePrototypeCreation(beanName);
		try {
			return createBean(beanName, mbd, args);
		}
		finally {
			afterPrototypeCreation(beanName);
		}
	});
	bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值