I would recommend to look into plain Spring configuration first to get a feel of how fundamental things (like injection) work. If you manage to get a hang of it in Spring, the process will be very similar in Spring MVC/Spring Boot/etc. Personally, I find it very frustrating trying to juggle multiple concepts (view resolvers, different configuration files, views, repositories, multiple annotations, multiple ways of configuration, etc.) at once, so I tend to start from the simplest concepts and build my way up. Once you are comfortable with how injection works, you can easily apply this knowledge elsewhere.
As for java config and annotations, they do allow for much quicker and cleaner development. XML is quite verbose, hard to maintain and is very prone to errors, in part because IDEs are generally more helpful when working with java based configuration. Perhaps that is why you read that XML is being deprecated. I would recommend to go for java/auto configuration rather than XML one, unless you really need to (or are interested in it).
Now onto how to do it. A complete (but minimal) working Spring example:
/* Bean definition
@Component tells Spring that this is a bean. There are a few similar annotations.
It will be discovered during the component scan, as it has @Component annotation */
package main.java.org.example;
import org.springframework.stereotype.Component;
@Component
public class Greeting {
private String greeting = "Hello";
public String getGreeting() {
return this.greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
/* Another bean definition.
It has another bean as a dependency, which we inject with a setter. */
package main.java.org.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GreetingCollector {
private Greeting greeting;
/* This is how you do setter injection */
@Autowired
public void setGreeting(Greeting greeting) {
this.greeting = greeting;
}
public String getGreeting() {
return greeting.getGreeting();
}
}
/* This is a minimal config class.
@ComponentScan instructs to look for classes that are
annotated with @Component annotation (in other words, beans) */
package main.java.org.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan
@Configuration
public class Config {}
If you want to do it explicitly:
package main.java.org.example;
import main.java.org.example.GreetingCollector;
import main.java.org.example.Greeting;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Bean
public Greeting greeting() {
return new Greeting();
}
@Bean
public GreetingCollector greetingCollector(Greeting greeting) {
return new GreetingCollector(greeting);
}
}
And if you want to run it just to see how it works:
import main.java.org.example.Config;
import main.java.org.example.GreetingCollector;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AppContext {
public static void main(String args[]) {
System.out.println("Configuring application context...");
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
GreetingCollector collector = (GreetingCollector) context.getBean("greetingCollector");
System.out.println(collector.getGreeting());
}
}
Naturally, Spring web application would be a bit different, but the basic injection idea is the same. First, you need to declare beans (either by using @Bean, @Component or any other annotation: see here and here for differences). You annotate either a setter or constructor (or even a field) with @Autowired, specify parameters (which do not necessarily need to be concrete classes - interfaces, abstract classes are fine, too), assign them to appropriate fields. Create a config class which takes cares of bean instantiation. You do not need to have your components in the same folder as config classes, as you can always specify where to look for components. Finally, if you want a more fine grained control, you can always declare beans explicitly in configuration class (so called JavaConfig, whereas @ComponentScan
based config might sometimes be called autoconfig). This should be enough to get you started and give you vocabulary to search for more advanced stuff.
And of course, with Spring Boot everything is even more abstracted away/quicker.