15 Annotation-based configuration
In addition to configuring Spring using XML alone, we can also use annotations to configure the corresponding bean definitions. For example, which classes are to be defined as beans, what content needs to be injected into the corresponding beans, etc. XML definitions and annotation definitions can coexist in Spring configuration.
15.1 Enabling support for annotations
If you need to use annotations to configure bean definitions, first we need to enable Spring's support for annotations. The easiest way is to introduce the namespace corresponding to the context in the Spring configuration file, and then define one in it <context:annotation-config/>
.
<?xml version="1.0" encoding="UTF-8"?>
<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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- enable support for annotations -->
< context : annotation-config />
</beans>
Once defined <context:annotation-config/>
, Spring will automatically register bean definitions for supporting annotations such as CommonAnnotationBeanPostProcessor
, RequiredAnnotationBeanPostProcessor
, PersistenceAnnotationBeanPostProcessor
and AutowiredAnnotationBeanPostProcessor
.
15.2 @Required
@Required
The annotation is used to mark the set method corresponding to the attribute, indicating that the corresponding attribute is not allowed to be empty after the initialization method of the corresponding bean is called. This annotation is mainly used for an annotation check to prevent the null pointer problem when we use the corresponding property to operate at runtime.
public class Hello {
private World world;
public World getWorld() {
return world;
}
@Required
public void setWorld(World world) {
this.world = world;
}
}
15.3 @Autowired
@Autowired
Annotations are used to indicate automatic injection, which can be defined on properties, set methods, constructors, etc. After using it for annotation, Spring will automatically inject the corresponding content, and the default is to inject according to the type. The content injected using the @Autowired annotation is @Required by default, that is, after the corresponding bean is fully initialized, the corresponding property cannot be empty and must be injected. It can be specified by specifying the require attribute of @Autowired. The default is true, that is, injection must be performed.
15.3.1 Annotation on properties
public class Hello {
@Autowired
private World world;
}
15.3.2 Set as optional injection
public class Hello {
@Autowired(required=false)
private World world;
}
15.3.3 Annotation on set methods
public class Hello {
private World world;
@Autowired
public void setWorld(World world) {
this.world = world;
}
}
15.3.4 Annotation on common methods
Spring also supports automatic injection through common methods, and the corresponding common methods can receive one or more parameters.
public class Hello {
private BeanA beanA;
private World world;
@Autowired
public void inject(World world, BeanA beanA) {
this.world = world;
this.beanA = beanA;
}
}
15.3.5 Annotation on the constructor
@Autowired
It can also be marked on the constructor to complete the automatic injection of constructor parameters.
public class Hello {
private World world;
@Autowired
public Hello(World world) {
this.world = world;
}
}
But one thing to note is that the content injected using @Autowired is @Required by default, that is, it cannot be empty. When our bean class definition has multiple constructors, Spring allows us to annotate with @Autowired on multiple constructors, but when annotated with @Autowired on multiple constructors, we must specify the value of the corresponding required attribute is false. The following two constructors are both @Autowired and @Required is not acceptable.
public class Hello {
private World world;
private BeanA beanA;
@Autowired
public Hello(World world) {
this.world = world;
}
@Autowired
public Hello(World world, BeanA beanA) {
this.world = world;
this.beanA = beanA;
}
}
By setting the corresponding required attribute to false, our definition is legal again. At this time, Spring will look for the bean corresponding to the parameter type of the corresponding constructor in the bean container, and then use the constructor that can satisfy the most constructor parameters for injection. In the following example, when both the World type bean and the BeanA type bean can be found in the bean container, it will be injected through the second constructor, otherwise it will be the first one.
public class Hello {
private World world;
private BeanA beanA;
@Autowired(required=false)
public Hello(World world) {
this.world = world;
}
@Autowired(required=false)
public Hello(World world, BeanA beanA) {
this.world = world;
this.beanA = beanA;
}
}
15.3.6 Injecting arrays, collection types, etc.
@Autowired
In addition to injecting a single bean object, it can also inject beans of array type, collection type, and Map type whose key is String. When an array type or a collection type needs to be injected, Spring will find all the beans of the corresponding type in the bean container, and then inject them into the corresponding array or collection as elements, if the beans of the corresponding type are implemented If the Ordered interface is selected, Spring will also add them in ascending order according to the return result of the getOrder() method of the Ordered interface when injecting them as an element. When a Map type whose key is String type needs to be automatically injected, Spring will look for all beans of the corresponding type of Map value in the bean container, and then inject them into the corresponding bean name with the corresponding bean name, that is, the beanName in the bean definition as the key. in the Map. Spring cannot automatically inject Maps whose keys are of non-String types.
public class Hello {
@Autowired
private World[] worldArray;
@Autowired
private List<World> worldList;
@Autowired
private Set<World> worldSet;
@Autowired
private Map<String, World> worldMap;
}
15.3.7 Injecting ApplicationContext, etc.
We can also automatically inject content related to Spring's internal mechanisms, such as BeanFactory, ApplicationContext, Environment, etc., through @Autowired.
public class Hello {
@Autowired
private BeanFactory beanFactory;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ConfigurableApplicationContext configurableContext;
@Autowired
private Environment environment;
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private MessageSource messageSource;
@Autowired
ResourcePatternResolver resourcePatternResolver;
}