spring中自定义bean的作用域

一、自定义作用域需要实现Scope接口

这块实现的作用域是线程级别的

package com.sunshine.boot.common;

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

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 控制bean的作用域是线程级别的
 */
public class CustomThreadScope implements Scope {

    public static final String THREAD_SCOPE = "thread";

    private ThreadLocal<Map<String, Object>> beanMapThreadLocal = new ThreadLocal() {
        @Override
        protected Object initialValue() {
            return new HashMap<>();
        }
    };

    /**
     * 返回当前作用域中name对应的bean对象
     * name:需要检索的bean的名称
     * objectFactory:如果name对应的bean在当前作用域中没有找到,那么可以调用这个ObjectFactory来创建这个对象
     **/

    @Override
    public Object get(String s, ObjectFactory<?> objectFactory) {
        Object bean = beanMapThreadLocal.get().get(s);
        if(bean == null) {
            bean = objectFactory.getObject();
            beanMapThreadLocal.get().put(s,bean);
        }
        return bean;
    }


    /**
     * 将name对应的bean从当前作用域中移除
     **/
    @Override
    public Object remove(String s) {
        return this.beanMapThreadLocal.get().remove(s);
    }

    /**
     * 用于注册销毁回调,如果想要销毁相应的对象,则由Spring容器注册相应的销毁回调,
     * 而由自定义作用域选择是不是要销毁相应的对象
     */
    @Override
    public void registerDestructionCallback(String s, Runnable runnable) {
        //bean作用域范围结束的时候调用的方法,用于bean清理
        System.out.println(s);
    }

    /**
     * 用于解析相应的上下文数据,比如request作用域将返回request中的属性。
     */
    @Override
    public Object resolveContextualObject(String s) {
        return null;
    }

    /**
     * 作用域的会话标识,比如session作用域将是sessionId
     */
    @Override
    public String getConversationId() {
        return null;
    }
}

二、创建bean的实体

package com.sunshine.boot.DTO;


import com.sunshine.boot.common.CustomThreadScope;
import lombok.Data;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("threadBean")
@Scope(CustomThreadScope.THREAD_SCOPE)

public class BeanScopeItem {

}

三、测试

package com.sunshine.boot.common;

import com.sunshine.boot.BootTest01;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;

public class CustomThreadScopeTest {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(BootTest01.class, args);
        context.getBeanFactory().registerScope(CustomThreadScope.THREAD_SCOPE,new CustomThreadScope());

        for(int i = 0; i < 2; i++) {
            new Thread(() -> {

                Object threadBean = context.getBean("threadBean");
                System.out.println(Thread.currentThread() + "," + context.getBean("threadBean"));

                // 若不执行下面这行代码 threadBean和threadBean1是同一个对象 即bean的作用域是线程级别的
                // 若执行下面这行代码 threadBean和threadBean1不是同一个对象
               // context.getBeanFactory().destroyScopedBean("threadBean");

                Object threadBean1 = context.getBean("threadBean");

                System.out.println("threadBean和threadBean1是否相等:" + (threadBean == threadBean1));
                System.out.println(Thread.currentThread() + "," + context.getBean("threadBean"));
            }).start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值