为了账号安全,请及时绑定邮箱和手机立即绑定

如何配置 Bean 原型范围提供程序以在 Bean 创建时使用会话信息?

如何配置 Bean 原型范围提供程序以在 Bean 创建时使用会话信息?

胡说叔叔 2023-06-21 15:55:43
每次访问代理以获取实例时,我都需要提供基于会话信息的 bean。我怎样才能做到这一点?现在我尝试了以下。例如:第一个类定义了一个会话范围的 bean。@Component@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)public class BeanSession implements Serializable {    private Serializable rootState;    public <T extends Serializable> T getRootState() {        return (T) rootState;    }    public void setRootState(Serializable rootState) {        this.rootState = rootState;    }}第二类有一些与他们的领域相关的逻辑,也知道如何提供信息。必须每次都创建 bean,因为信息在线程处理期间可能会发生变化。因此,每次Attribute1访问时,我一定会得到包含新信息的 bean。@Servicepublic class Attribute1Service {    @Resource    private BeanSession beanSession;    public void setDefaultValue() {        Configuration configuration = beanSession.getRootState();        configuration.getAttribute1().setValue("VALUE 1");    }    @Bean    public Attribute1 attribute1() {        Configuration configuration = beanSession.getRootState();        return configuration.getAttribute1();    }}最后,第三个类声明attribute1as 依赖项来执行自己的逻辑。@Servicepublic class Attribute2Service {    @Resource    private BeanSession beanSession;    @Resource    private Processor processor;    @Resource    private Attribute1 attribute1;    public void defineAttribute2() {        Configuration configuration = beanSession.getRootState();        String value = processor.getValue(configuration, attribute1);        configuration.getAttribute2().setValue(value);    }    public void defineAttribute3() {        Configuration configuration = beanSession.getRootState();        String value = processor.getValue(configuration, attribute1);        configuration.getAttribute3().setValue(value);    }}我不想从头开始访问信息attribute1,因为这会在信息提供者和消费者之间造成硬耦合。beanSessionAttribute2Service
查看完整描述

2 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

异常说明了一切 - attribute1 bean 是在应用程序初始化期间创建的(通过会话作用域 bean),但没有与请求绑定的线程。您还应该代理您的 attribute1 bean,因为您将其注入到单例(属性 2 服务。)



查看完整回答
反对 回复 2023-06-21
?
暮色呼如

TA贡献1853条经验 获得超9个赞

基于 Alexander.Furer 给出的见解。我创建了自己的作用域,并管理它来调用 bean 提供者,以便在Attribute1方法的每次访问中都拥有新鲜的 bean。


为此,我扩展了以下范围:


// Register scope as "runtime"

public class RuntimeScope implements Scope {


    @Override

    public Object get(String name, ObjectFactory<?> objectFactory) {

        return objectFactory.getObject();

    }


    ...

}

新Attribute1服务:


@Service

public class Attribute1Service {


    @Resource

    private BeanSession beanSession;


    public void setDefaultValue() {

        Configuration configuration = beanSession.getRootState();

        configuration.getAttribute1().setValue("VALUE 1");

    }


    @Bean

    @Scope(value = "runtime", proxyMode = ScopedProxyMode.TARGET_CLASS)

    public Attribute1 attribute1() {

        Configuration configuration = beanSession.getRootState();

        return configuration.getAttribute1();

    }


}

消费者Attribute2服务:


@Service

public class Attribute2Service {


    @Resource

    private BeanSession beanSession;


    @Resource

    private Processor processor;


    @Resource

    private Attribute1 attribute1;


    public void defineAttribute2() {

        Configuration configuration = beanSession.getRootState();

        String value = processor.getValue(configuration, attribute1.getValue()); // Will call Attribute1 service to require the fresh bean

        configuration.getAttribute2().setValue(value);

    }


    public void defineAttribute3() {

        Configuration configuration = beanSession.getRootState();

        String value = processor.getValue(configuration, attribute1.getValue()); // Will call Attribute1 service to require the fresh bean

        configuration.getAttribute3().setValue(value);

    }


}

我没有看到的问题是 Attribute1 应该是处理 bean 实例化的代理。因此,通过创建我自己的范围,我可以保证访问 attribute1(由Attribute2Servicewith生成attribute1.getValue())方法将创建一个新的 bean(由 提供Attribute1Service)。


查看完整回答
反对 回复 2023-06-21
  • 2 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信