Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can spring framework override Annotation-based configuration with XML-based configuration?

Can spring framework override Annotation-based configuration with XML-based configuration? I need to change a dependency of a bean which is already defined via annotations and i am not the author of the bean.

like image 823
mert inan Avatar asked Feb 09 '11 10:02

mert inan


People also ask

Can we use both annotation and XML based configuration?

Yes, you can use XML, annotations, or a mix.

Are annotations better than XML for configuring Spring?

XML configurations can take a lot of work when there are a lot of beans, while annotations minimize the XML configurations. Annotation injection is performed before XML injection. Thus, XML configurations will override that of the annotations.

Does Spring core supports XML Java and annotation based configuration?

Traditionally, Spring allows a developer to manage bean dependencies by using XML-based configuration. There is an alternative way to define beans and their dependencies. This method is a Java-based configuration. Unlike the XML approach, Java-based configuration allows you to manage bean components programmatically.

Does Spring boot avoid XML configuration?

Is it possible to avoid using xml in Spring or better to mix xml files and annotations? Yes, it is. Spring now promotes Java configuration, and it's perfectly doable (I'm doing it) and even easy to only use Java to configure your Spring app. Even without using Boot.


2 Answers

i did not know that spring can mix configurations. here is the detailed and very useful example.

Bean1 is the actual bean we're configuring.

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 is dependency interface

package spring;

public interface Fire {

    public void fire();
}

and dummy implementation 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());
    }
}

and dummy implementation 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>

and main class

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());
    }
}

here is the output

init
class spring.FireImpl2
nice
destroy

Although annotation resolves dependency to FireImpl1, xml config overrided with FireImpl2. very nice.

like image 144
mert inan Avatar answered Sep 20 '22 03:09

mert inan


This should be OK. A Spring bean context allows you to redefine beans, with "later" definitions overriding "earlier ones". This should apply to XML-defined beans as well as annotation-defined beans, even if they're mixed.

For example, if you have

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

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

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

In this case, the XML definition of beanA should take precedence.

like image 42
skaffman Avatar answered Sep 20 '22 03:09

skaffman