Как внедрить переменные-члены, у которых функции сеттера определены по-разному? - PullRequest
0 голосов
/ 19 января 2019

У меня есть класс построителя, определенный ниже в сторонней библиотеке:

открытый класс KeyBuilder {

private A a;
private B b;
private C c;

public KeyBuilder withA(final A a){
    this.a = a;
    return this;
}

public KeyBuilder withB(final B b){
    this.b = b;
    return this;
}

public KeyBuilder withC(final C c){
    this.c = c;
    return this;
}

public Key build() {
    return new Key(this.a, this.b, this.c);
}

}

Я пытаюсь создать экземпляр Key с помощью компоновщика с конфигурацией нижеприведенной пружины:

<!-- A -->
<bean id="A" class="com.example.A" />

<!-- B -->
<bean id="B" class="com.example.B" />

<!-- C -->
<bean id="C" class="com.example.C" />

<!-- KeyBuilder -->
<bean id="KeyBuilder" class="com.example.KeyBuilder">
    <property name="a" value="A"/>
    <property name="b" value="B"/>
    <property name="c" value="C"/>
</bean>

<!-- Key -->
<bean id="Key" factory-bean="KeyBuilder" factory-method="build" />

Однако, это терпит неудачу с ошибкой ниже:

Error creating bean with name 'KeyBuilder' defined in URL [file:spring-config.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'a' of bean class [com.example.KeyBuilder]: Bean property 'a' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

Как я понимаю, это будет просто работать, если я изменю имена методов в построителе с 'withA / withB / withC' на 'setA / setB / setC', но у меня нет этой опции, поскольку библиотека управляется сторонней организацией .

Может кто-нибудь предложить, если есть способ передачи метода установки в теге свойства или альтернативный способ решения проблемы здесь.

1 Ответ

0 голосов
/ 19 января 2019

Если вы используете конфигурацию на основе аннотаций, вы можете легко сделать это, программно создав ключ в методе @Bean, как обычно.

Но при условии, что вы можете использовать только конфигурацию XML, вы можете реализовать FactoryBean, который позволяет вам определить, как создать программный компонент:

public class KeyFactoryBean implements FactoryBean<Key> {

    private A a;
    private B b;
    private C c;

    public void setA(A a){
       this.a= a;
    }

    public void setB(B b){
       this.b= b;
    }

    public void setC(C c){
       this.c= c;
    }

    @Override
    public Key getObject() throws Exception {
        return new KeyBuilder()
                .withA(this.a)
                .withB(this.b)
                .withC(this.c)
                .build();
    }

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

Затем конфигурация XML:

<bean id="Key" class="com.example.KeyFactoryBean">
    <property name="a" ref="A" />
    <property name="b" ref="B"/>
    <property name="c" ref="C" />
</bean>
...