SpEL:在 bean 实例化期间获取当前 bean 名称
SpEL: get current bean name during bean instantiation
我正在尝试使用 SpEL 获取当前正在实例化的 bean 的名称,以允许使用 @PropertySource
提供的不同属性创建多个相同 class 的 bean。我希望得到如下内容:
public class SampleBean {
@Value("${#{CurrentBeanName}.val}")
private String val
}
其他bean:
public class OtherBean {
@Autowired
@Qualifier(name="BeanA")
SampleBean beanA;
@Autowired
@Qualifier(name="BeanB")
SampleBean beanB;
}
属性文件:
BeanA.val=VALUE A
BeanB.val=VALUE B
如果我将 beanName=BeanA
添加到我的属性文件中,我就可以使用它
@Value("${${beanName}.val}")
关于 #{BeanName}
做什么的任何想法?如果这是不可能的,那就这样吧,但如果可行,它将比我当前的解决方案干净得多。
编辑:
或者有什么方法可以将常量从 xml bean 定义传递给 SpEL?示例:
<bean id="BeanA" class="...">
<property name="prefix" value="BeanA"/>
</bean>
java:
public class SampleBean {
@Value("${#{prefix}.val}")
private String val
}
任何类型的属性或任何东西都可以
编辑 2:
这在旧的基于 XML 的配置中是微不足道的
spring.xml:
<bean id="beanA" class="SampleBean">
<property name="val" value="${BeanA.val}"/>
</bean>
<bean id="beanB" class="SampleBean">
<property name="val" value="${BeanB.val}"/>
</bean>
SampleBean.java:
public class SampleBean {
private String val;
public void setVal (String val) {
this.val = val;
}
}
然而,当切换到新的 @Value
注释以摆脱所有设置器时,似乎不支持具有 diff 属性的非单例(即无法动态过滤 @Value
参数关于 bean 创建)
否;无法引用当前 bean。
编辑
为了解决您在下面的评论,Java 配置等效于
<bean id="BeanA" class="com.my.Foo">
<property name="prefix" value="BeanA"/>
</bean>
是
@Bean
public Foo BeanA() {
Foo a = new Foo();
a.setPrefix("BeanA");
}
尽管按照惯例,您可能会将其命名为 beanA
。
如果您有单例 bean 类型,您可以只使用 static final
变量作为名称,然后引用它。但更大的问题是,如果您开始依赖 Spring
bean 名称,您将破坏控制主体的 Spring
反转,这就是为什么没有完成此类事情的原因。非常想专注于为您的项目创建模块和域。如果您开始直接访问来自 Spring 上下文的组件(例如 bean 名称),您会发现您的模块会变得脆弱,难以更改并且很难推理,因为它们开始依赖于看似不相关的模块,例如 Spring 依赖注入框架。尽管您可能有一个有效的用例来执行此操作,但您只需要非常非常小心。
我正在尝试使用 SpEL 获取当前正在实例化的 bean 的名称,以允许使用 @PropertySource
提供的不同属性创建多个相同 class 的 bean。我希望得到如下内容:
public class SampleBean {
@Value("${#{CurrentBeanName}.val}")
private String val
}
其他bean:
public class OtherBean {
@Autowired
@Qualifier(name="BeanA")
SampleBean beanA;
@Autowired
@Qualifier(name="BeanB")
SampleBean beanB;
}
属性文件:
BeanA.val=VALUE A
BeanB.val=VALUE B
如果我将 beanName=BeanA
添加到我的属性文件中,我就可以使用它
@Value("${${beanName}.val}")
关于 #{BeanName}
做什么的任何想法?如果这是不可能的,那就这样吧,但如果可行,它将比我当前的解决方案干净得多。
编辑:
或者有什么方法可以将常量从 xml bean 定义传递给 SpEL?示例:
<bean id="BeanA" class="...">
<property name="prefix" value="BeanA"/>
</bean>
java:
public class SampleBean {
@Value("${#{prefix}.val}")
private String val
}
任何类型的属性或任何东西都可以
编辑 2:
这在旧的基于 XML 的配置中是微不足道的
spring.xml:
<bean id="beanA" class="SampleBean">
<property name="val" value="${BeanA.val}"/>
</bean>
<bean id="beanB" class="SampleBean">
<property name="val" value="${BeanB.val}"/>
</bean>
SampleBean.java:
public class SampleBean {
private String val;
public void setVal (String val) {
this.val = val;
}
}
然而,当切换到新的 @Value
注释以摆脱所有设置器时,似乎不支持具有 diff 属性的非单例(即无法动态过滤 @Value
参数关于 bean 创建)
否;无法引用当前 bean。
编辑
为了解决您在下面的评论,Java 配置等效于
<bean id="BeanA" class="com.my.Foo">
<property name="prefix" value="BeanA"/>
</bean>
是
@Bean
public Foo BeanA() {
Foo a = new Foo();
a.setPrefix("BeanA");
}
尽管按照惯例,您可能会将其命名为 beanA
。
如果您有单例 bean 类型,您可以只使用 static final
变量作为名称,然后引用它。但更大的问题是,如果您开始依赖 Spring
bean 名称,您将破坏控制主体的 Spring
反转,这就是为什么没有完成此类事情的原因。非常想专注于为您的项目创建模块和域。如果您开始直接访问来自 Spring 上下文的组件(例如 bean 名称),您会发现您的模块会变得脆弱,难以更改并且很难推理,因为它们开始依赖于看似不相关的模块,例如 Spring 依赖注入框架。尽管您可能有一个有效的用例来执行此操作,但您只需要非常非常小心。