gpt4 book ai didi

java - Spring 中的共享原型(prototype) bean

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:49:19 25 4
gpt4 key购买 nike

我需要创建一个 spring bean 的多个实例(我们称之为 MainPrototypeBean),我可以使用 prototype 范围来完成。它依赖于其他一些 bean,我想在每次创建主 bean 时创建它们的新实例。但是,某些 bean 之间存在共享依赖关系,我们称之为 SharedPrototypeBean。如何在每个依赖 bean 中注入(inject)相同的 SharedPrototypeBean 实例,同时为每个 MainPrototypeBean 创建一个新实例?

我正在考虑实现自定义范围,但我希望找到一种更简洁的方法。使任何 bean 成为单例都不是一种选择,因为它们需要在 MainPrototypeBean 的不同实例之间隔离。

这是我正在尝试做的一个例子:

@SpringBootApplication
public class DIDemo {
public static void main(String[]args){
ConfigurableApplicationContext context = SpringApplication.run(DIDemo.class, args);
context.getBean(MainPrototypeBean.class);
}

@Component @Scope("prototype") static class SharedPrototypeBean {}

@Component @Scope("prototype") static class FirstPrototypeBean {
@Autowired SharedPrototypeBean shared;
@PostConstruct public void init() {
System.out.println("FirstPrototypeBean.init() with shared " + shared);
}
}

@Component @Scope("prototype") static class SecondPrototypeBean {
@Autowired SharedPrototypeBean shared;
@PostConstruct public void init() {
System.out.println("SecondPrototypeBean.init() with shared " + shared);
}
}

@Component @Scope("prototype") static class MainPrototypeBean {
@Autowired FirstPrototypeBean first;
@Autowired SecondPrototypeBean second;
}
}

执行结果为:

FirstPrototypeBean.init() with shared DIDemo$SharedPrototypeBean@1b84f475
SecondPrototypeBean.init() with shared DIDemo$SharedPrototypeBean@539d019

最佳答案

您可以将FactoryBean 用于复杂的构造逻辑。实现其抽象子类 AbstractFactoryBean 以创建 MainPrototypeBean,并将所有三个依赖 bean 注入(inject)其中。然后,您可以在 createInstance 方法中将它们连接在一起。

FactoryBean 实现:

public class MainFactoryBean extends AbstractFactoryBean<MainPrototypeBean> implements FactoryBean<MainPrototypeBean> {

private FirstPrototypeBean firstPrototype;
private SecondPrototypeBean secondPrototpye;
private SharedPrototypeBean sharedPrototype;

public MainFactoryBean(FirstPrototypeBean firstPrototype, SecondPrototypeBean secondPrototype, SharedPrototypeBean sharedPrototype) {
this.firstPrototype = firstPrototype;
this.secondPrototpye = secondPrototype;
this.sharedPrototype = sharedPrototype;
}


@Override
protected MainPrototypeBean createInstance() throws Exception {
MainPrototypeBean mainPrototype = new MainPrototypeBean();
firstPrototype.setSharedPrototypeBean(sharedPrototype);
secondPrototpye.setSharedPrototypeBean(sharedPrototype);
mainPrototype.first = firstPrototype;
mainPrototype.second = secondPrototpye;

//call post construct methods on first and second prototype beans manually
firstPrototype.init();
secondPrototpye.init();
return mainPrototype;
}

@Override
public Class<?> getObjectType() {
return MainPrototypeBean.class;
}
}

注意:sharedPrototype 是在第一个和第二个原型(prototype)的生命周期中的构建后阶段之后注入(inject)的。因此,如果这些 bean 中有需要 sharedPrototype 的构建后逻辑,则需要在创建 MainPrototypeBean 时手动调用 init 方法。

您的注释 - 配置因此而改变。 sharedPrototype 属性不再 Autowiring (它们在 FactoryBean 中设置),并且 MainPrototypeBean 不再注释。相反,您需要创建 MainFactoryBean

@Configuration
public class JavaConfig {

//method name is the name refers to MainPrototypeBean, not to the factory
@Bean
@Scope("prototype")
public MainFactoryBean mainPrototypeBean(FirstPrototypeBean firstPrototype, SecondPrototypeBean secondPrototype, SharedPrototypeBean sharedPrototype) {
return new MainFactoryBean(firstPrototype, secondPrototype, sharedPrototype);
}
//Annotations are not needed anymore
static class MainPrototypeBean {
FirstPrototypeBean first;
SecondPrototypeBean second;
}

@Component
@Scope("prototype")
static class SharedPrototypeBean {
}

@Component
@Scope("prototype")
static class FirstPrototypeBean {
private SharedPrototypeBean shared;
//no autowiring required
public void setSharedPrototypeBean(SharedPrototypeBean shared) {
this.shared = shared;
}
@PostConstruct
public void init() {//reference to shared will be null in post construction phase
System.out.println("FirstPrototypeBean.init() with shared " + shared);
}
}

@Component
@Scope("prototype")
static class SecondPrototypeBean {

private SharedPrototypeBean shared;
public void setSharedPrototypeBean(SharedPrototypeBean shared) {
this.shared = shared;
}

@PostConstruct
public void init() {
System.out.println("SecondPrototypeBean.init() with shared " + shared);
}
}
}

关于java - Spring 中的共享原型(prototype) bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46564630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com