Может ли Spring Framework переопределить конфигурацию на основе аннотаций конфигурацией на основе XML?

Может ли Spring Framework переопределить конфигурацию на основе аннотаций конфигурацией на основе XML? Мне нужно изменить зависимость bean-компонента, который уже определен с помощью аннотаций, и я не являюсь автором bean-компонента.


person mert inan    schedule 09.02.2011    source источник


Ответы (2)


Это должно быть в порядке. Контекст bean-компонента Spring позволяет переопределять bean-компоненты, при этом «более поздние» определения переопределяют «более ранние». Это должно применяться к компонентам, определенным XML, а также к компонентам, определенным аннотациями, даже если они смешаны.

Например, если у вас есть

@Configuration
public class MyAnnotatedConfig {
   @Bean 
   public Object beanA() {
      ...
   }
}

<bean class="com.xyz.MyAnnotatedConfig"/>

<bean id="beanA" class="com.xyz.BeanA"/>

В этом случае XML-определение beanA должно иметь приоритет.

person skaffman    schedule 09.02.2011
comment
Однако это может не работать для полей @Autowired в зависимости от типа? Кажется, это выбрасывает org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.xyz.BeanA] is defined: expected single matching bean but found 2: [beanA, beanA] (Spring 3.2) - person Arjan; 18.12.2012

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

Bean1 — это фактический bean-компонент, который мы настраиваем.

package spring;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Bean1 {

    private String naber;

    @Autowired
    @Qualifier("FireImpl1")
    private Fire fire;

    @PostConstruct
    public void init() {
        System.out.println("init");
        getFire().fire();
    }

    @PreDestroy
    public void destroy() {
        System.out.println("destroy");
    }

    public void setNaber(String naber) {
        this.naber = naber;
    }

    public String getNaber() {
        return naber;
    }

    public void setFire(Fire fire) {
        this.fire = fire;
    }

    public Fire getFire() {
        return fire;
    }
}

Fire — это интерфейс зависимостей

package spring;

public interface Fire {

    public void fire();
}

и фиктивная реализация 1

package spring;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
@Qualifier("FireImpl1")
public class FireImpl1 implements Fire {

    public void fire() {
        System.out.println(getClass());
    }
}

и фиктивная реализация 2

package spring;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
@Qualifier("FireImpl2")
public class FireImpl2 implements Fire {

    public void fire() {
        System.out.println(getClass());
    }
}

config.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <context:component-scan base-package="spring" />
    <bean id="bean1" class="spring.Bean1">
        <property name="naber" value="nice" />
        <property name="fire" ref="fireImpl2" />
    </bean>
</beans>

и основной класс

package spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Spring {

    public static void main(String[] args) {

        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring/config.xml");
        applicationContext.registerShutdownHook();
        Bean1 bean = (Bean1) applicationContext.getBean("bean1");
        System.out.println(bean.getNaber());
    }
}

вот результат

init
class spring.FireImpl2
nice
destroy

Хотя аннотация разрешает зависимость от FireImpl1, конфигурация xml переопределяет FireImpl2. очень хорошо.

person mert inan    schedule 09.02.2011