background
When we talk about Spring, we will definitely mention IOC containers and DI dependency injection. Spring injects methods of labeling classes as beans into the IOC container, achieving the effect of controlling inversion. Then when we first started to contact Beans, we must use xml files and inject them one by one, just like the following.
If our projects are generally large, they require hundreds of beans to use, which makes it very cumbersome to write. Then Spring helps us implement a method of implementing injection through annotations. Just add the corresponding annotation to the class you need to inject, and Spring will help us scan them to implement the injection.
How to scan packages for xml
<context:component-scan base-package=""/>
General form of injection by annotation
Generally speaking, there is a most straightforward and easy-to-understand way to implement injection. I won’t say much about nonsense, just post the code first.
- Bean class
public class MyBean{
}
- Configuration class
//Create a class configuration file
@Configuration
public class MyConfiguration{
//Leave a bean to Spring for management
@Bean
public MyBean myBean(){
return new MyBean();
}
}
- Test class
It is a little different from xml. Here in Test, the instantiated classPathXmlApplicationContext is no longer the ClassPathXmlApplicationContext instance, but the obtained AnnotationConfigApplicationContext instance.
ApplicationContext context = new AnnotationConfigApplicationContext();
MyBean myBean = ("myBean",);
("myBean = " + myBean);
In the above code, MyBean is a bean that we need Spring to manage. It is just a simple class. In MyConfiguration, we first use the @Configuration annotation to mark the class, so that the class is a Spring configuration class, and it will be loaded when loading the configuration.
In MyConfiguration, we can see that there is a method that returns an instance of MyBean, and the method is marked with @Bean annotation, indicating that this is a method of injecting the bean, which will inject the returned bean into the IOC.
Injection of Bean by constructive method
When we generate a Bean instance, we can use the Bean constructor to inject the Bean implementation. Look directly at the code
- Bean class
@Component
public class MyBeanConstructor {
private AnotherBean anotherBeanConstructor;
@Autowired
public MyBeanConstructor(AnotherBean anotherBeanConstructor){
= anotherBeanConstructor;
}
@Override
public String toString() {
return "MyBean{" +
"anotherBeanConstructor=" + anotherBeanConstructor +
'}';
}
}
- AnotherBean class
@Component(value="Bean's id, default to class name small camel")
public class AnotherBean {
}
- Configuration class
@Configuration
@ComponentScan("")
public class MyConfiguration{
}
Here we can find that the code injected is different from the general method. Let’s take a look at what the new annotations mean:
- @AutoWired
Simple and crude, the translation directly means automatic assembly: wrench:, I don’t understand why it is called automatic assembly: wrench:? You will know after reading the explanation of the next annotation. If you specify a bean's id when injecting here, you must use the @Qualifier annotation
- @Component (default singleton mode)
What? ? This translates to parts, how does it feel like repairing a car? ? Yes, the way Spring manages beans is how to repair cars. When we need to turn a class into a bean and be injected by Spring, we add annotation part @Conmonent, so we can assemble the bean like a part when loading it:wrench: On this IOC car
Here we have several other annotations that can also implement this function, that is, the refined @Component:
- @Controller annotated in the Controller layer
- @Service is marked in the Service layer
- @Repository annotated at dao layer
- @ComponentScan("")
Or translation, part scanning, let’s look at which “parts” (classes) need to be loaded in the “part warehouse” in the brackets. Spring will scan the package and inject all the classes marked @Component.
It is easy to understand what is injected through the construction method here. When we assemble the MyBean part, we suddenly found that it must be installed in the IOC based on AnotherBean. Then we automatically assemble: wrench: AnotherBean in every time we assemble MyBean. For example: chestnut:
Take the car as an example. Do we have to start before stepping on the accelerator? ? The content of AutoWired here is like starting a car. If you don’t start, it will be useless if you step on the accelerator and he won’t leave.
Inject Beans through the set method
We can inject the Bean implementation into the set method of a property, and see the code
- MyBean class
@Component
public class MyBeanSet {
private AnotherBean anotherBeanSet;
@Autowired
public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
= anotherBeanSet;
}
@Override
public String toString() {
return "MyBeanSet{" +
"anotherBeanSet=" + anotherBeanSet +
'}';
}
}
- Configuration class and Test class
I won't post the same one
Here we find that in the setter method we have a @AutoWired. Unlike the above, we will not automatically assemble this object when instantiating the class:wrench:, but will assemble it when explicitly calling the setter.
Inject Beans through attributes
Our previous two injection methods are different, such as different time and more codes. If we pass the attributes, it is
@Component
public class MyBeanProperty {
@Autowired
private AnotherBean anotherBeanProperty;
@Override
public String toString() {
return "MyBeanProperty{" +
"anotherBeanProperty=" + anotherBeanProperty +
'}';
}
}
Here we can see that our class needs to use AnotherBean instance object, and we can automatically assemble it through @AutoWired.
For some friends, how do Spring load it into IOC? Recommend to check out the reflection
Inject Beans via List
- MyBeanList class
@Component
public class MyBeanList {
private List<String> stringList;
@Autowired
public void setStringList(List<String> stringList) {
= stringList;
}
public List<String> getStringList() {
return stringList;
}
}
- MyConfiguration class
@Configuration
@ComponentScan("")
public class MyConfiguration {
@Bean
public List<String> stringList(){
List<String> stringList = new ArrayList<String>();
("List-1");
("List-2");
return stringList;
}
}
Here we inject MyBeanList and inject elements in the List one by one. The following is another way to inject List
- MyConfiguration class
@Bean
// Set the priority of bean injection through this annotation, not necessarily continuous numbers
@Order(34)
public String string1(){
return "String-1";
}
@Bean
@Order(14)
public String string2(){
return "String-2";
}
Injecting the same type as the generics in List will automatically match the types. There is no List feeling here in time, it is just the type of String, but it will inject it through the List Bean method.
The priority of the second method is higher than that of the first. When both exist, if you want to force the first method, you need to specify the id of the bean.
Inject Beans via Map
@Component
public class MyBeanMap {
private Map<String,Integer> integerMap;
public Map<String, Integer> getIntegerMap() {
return integerMap;
}
@Autowired
public void setIntegerMap(Map<String, Integer> integerMap) {
= integerMap;
}
}
@Bean
public Map<String,Integer> integerMap(){
Map<String,Integer> integerMap = new HashMap<String, Integer>();
("map-1",1);
("map-2",2);
return integerMap;
}
@Bean
public Integer integer1(){
return 1;
}
@Bean
public Integer integer2(){
return 2;
}
There are also two ways to inject Map type beans, and the priority value of the second type is higher than that of the first type.
The above are several ways of bean injection through annotation. You can compare the XML injection method to see.