gpt4 book ai didi

java - 使用 Java Config 覆盖 Autowiring setter

转载 作者:行者123 更新时间:2023-12-02 00:47:56 28 4
gpt4 key购买 nike

考虑下面的类:

public class MyBean {
private A a;

@Autowired(required=true)
public void setA(A a) {
this.a = a;
}

public A getA() {
return a;
}
}

在某些情况下,需要重写 Autowiring 注入(inject),例如,当 Spring 找不到单个候选注入(inject)时。在 XML 中我可以有以下示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="first" class="my.pkg.AImpl"/>
<bean id="second" class="my.pkg.AImpl"/>
<bean id="myBeanFirst" class="my.pkg.MyBean">
<property name="a" ref="first"/>
</bean>
<bean id="myBeanSecond" class="my.pkg.MyBean">
<property name="a" ref="second"/>
</bean>

</beans>

有没有办法用 Java Config 来做同样的事情?以下内容不起作用(我明白为什么),因为 Spring 尝试在从 myBean 方法返回后 Autowiring 该属性,但失败并出现 NoUniqueBeanDefinitionException:

@Configuration
public class MyConfig {
@Bean
public A first() {
return new AImpl();
}

@Bean
public A second() {
return new AImpl();
}

@Bean
public MyBean myBeanFirst(A first) {
MyBean myBean = new MyBean();
myBean.setA(first);
return myBean;
}

@Bean
public MyBean myBeanSecond(A second) {
MyBean myBean = new MyBean();
myBean.setA(first);
return myBean;
}
}

修改 MyBean 类并不总是一种选择,例如因为它来自外部库。在这种情况下我必须使用 XML 配置吗?

谢谢,安德里亚·波尔奇

更新感谢您提供的两个解决方案(按名称注入(inject)和使用 @Primary),但它们不能解决我的用例,所以我认为我需要更具体。

在我的用例中,MyBean 类来自外部库,因此不可能对其进行任何更改。我还需要有多个 MyBean 实例,每个实例注入(inject) A 接口(interface)的不同实例。我更新了上面的代码以反射(reflect)这一点(xml 和 java)。

有没有使用java config的解决方案?是否可以避免 Autowiring 对 MyBean 的依赖? (仅在该类的 bean 上,不要为上下文中的每个 bean 完全禁用 Autowiring )

最佳答案

好了,就到这里,相信这个答案能够满足您的需求。

我们需要的是 MergedBeanDefinitionPostProcessor 的实现,它将为 MyBean 类的属性 a 设置正确的值。这可以通过以下类来完成

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;


@Component
public class MyBeanPostProcessor implements MergedBeanDefinitionPostProcessor {


@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if(beanName.equals("myBeanFirst")) {
beanDefinition.getPropertyValues().add("a", getMyBeanFirstAImpl());
}
else if(beanName.equals("myBeanSecond")) {
beanDefinition.getPropertyValues().add("a", getMyBeanSecondAImpl());
}
}

private Object getMyBeanFirstAImpl() {
return new AImpl();
}

private Object getMyBeanSecondAImpl() {
return new AImpl();
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

正如您所看到的,这里的 Bean 名称是硬编码的,但它们可以设置在静态最终字符串中,以下代码中的 @Bean 注释也将使用该字符串

@Configuration
public class Configuration {



@Bean
public MyBean myBeanFirst() {
return new MyBean();
}

@Bean
public MyBean myBeanSecond() {
return new MyBean();
}

}

您会注意到,在下面的代码中,MyBean 创建方法中没有调用 setA,因为无论我们设置什么值(或者在本例中不设置),当 Spring 执行 bean 后处理器时,都将被覆盖。

如果您需要 A 的默认值(例如,您将其注入(inject)到其他 bean 中),请继续在之前的配置中定义 @Bean

关于java - 使用 Java Config 覆盖 Autowiring setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22416140/

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