Spring framework learning - annotation based container configuration for spring IOC

TyuIn 2022-01-26 11:12:58 阅读数:894

spring framework learning annotation based

Follow up with a blog :https://blog.csdn.net/qq_43605444/article/details/121954378?spm=1001.2014.3001.5502

10、 Annotation based container configuration

In the configuration Spring aspect , Is the annotation better than XML Better ?

  • The introduction of annotation based configuration puts forward whether this method is better than XML“ Better ” The problem of . The short answer is “ As the case may be ”. The long answer is that each method has its advantages and disadvantages , It's usually up to developers to decide which strategy is better for them . Because of the way they are defined , Annotations provide a lot of context in their declarations , This leads to shorter and simpler configurations . However ,XML Good at connecting components , Without touching their source code or recompiling them . Some developers prefer to place wiring close to the source , Others believe that annotated classes are no longer POJO, and , Configuration becomes decentralized and more difficult to control .
  • Whatever you choose ,Spring Can accommodate both styles , You can even mix them together . It's worth pointing out , Through its JavaConfig Options ,Spring Allow non-invasive use of annotations , Without touching the source code of the target component , And in terms of tools ,Spring Tools for Eclipse All configuration styles are supported .

XML Alternatives to settings are provided by annotation based configurations , It relies on byte symbol data to connect components rather than angle bracket declarations . Developers do not use XML To describe bean Connect , But through the related classes 、 Use annotations on method or field declarations to move the configuration into the component class itself . As the sample :AutowiredAnnotationBeanPostProcessor Described in , take BeanPostProcessor Used in conjunction with annotations is an extension Spring IoC Common methods of containers . for example ,Spring 2.0 Introduced the use of @Required Annotation enforces the possibility of mandatory attributes . Spring 2.5 Make it follow the same general method to drive Spring Dependency injection is possible .

essentially ,@Autowired Annotations provide information about Autowiring Collaborators The same functions described in , But it has more fine-grained control and wider applicability . Spring 2.5 Also added right JSR-250 Support for annotations , for example @PostConstruct and @PreDestroy. Spring 3.0 Added a pair included in javax.inject In bag JSR-330(Java Dependency injection ) Support for annotations , for example @Inject and @Named. More information about these annotations can be found in the relevant sections .

Note injection in XML Before injection . therefore ,XML The configuration will override the annotations of the attributes connected through these two methods .

As usual , You can register the post processor as a separate bean Definition , But it's also possible to do this through XML Of Spring The following tags are included in the configuration to implicitly register them ( Note that the namespace contains context ):

<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- Open the annotation -->
<context:annotation-config/>
</beans>

<context:annotation-config/> Element implicitly registers the following postprocessor :

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor
  • EventListenerMethodProcessor

<context:annotation-config/> Find only in the same application context that defines it bean The annotations on . It means , If you will <context:annotation-config/> Put it in DispatcherServlet Of WebApplicationContext in , It will only check the... In your controller @Autowired bean, Not your service . For more information , see also DispatcherServlet.

10.1 @Required

@Required The note applies to bean Property setting method , As shown in the following example :

public class SimpleMovieLister {

private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {

this.movieFinder = movieFinder;
}
// ...
}

This annotation indicates that you must pass... During configuration bean Explicit attribute values in the definition or by auto assembling to populate the affected properties bean attribute . If the affected bean attribute , The container will throw an exception .

This allows eagerness and explicit failure , Avoid future NullPointerException Examples or similar situations . We still recommend that you put assertions in bean Class itself ( for example , Put in init Method ). Even if you use classes outside the container , Doing so also enforces those required references and values .

RequiredAnnotationBeanPostProcessor Must be registered as bean To enable access to @Required Support for annotations .

@Required annotation and RequiredAnnotationBeanPostProcessor from Spring Framework 5.1 Start Formal abandonment , In favor of using constructor injection to make the required settings ( or InitializingBean.afterPropertiesSet() Custom implementation or customization of @PostConstruct Methods and bean Property setter method ).

 Insert picture description here
 Insert picture description here

10.2 Use @Autowired

JSR 330 Of @Inject Annotations can be used in place of... In the examples included in this section Spring Of @Autowired annotation .

You can use @Autowired Annotations apply to constructors , This is shown in the following example :

public class MovieRecommender {

private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {

this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}

from Spring Framework 4.3 Start , If target bean Only one constructor is defined , You no longer need to add... To this type of constructor @Autowired annotation . however , If more than one constructor is available and There is no lord / Default constructor , At least @Autowired Annotate one of the constructors , To indicate which... The container uses . For more information , See the discussion on constructor parsing .

 Insert picture description here
 Insert picture description here
 Insert picture description here
You can also @Autowired Annotations apply to traditional setter Method , This is shown in the following example :

public class SimpleMovieLister {

private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {

this.movieFinder = movieFinder;
}
// ...
}

 Insert picture description here
 Insert picture description here
 Insert picture description here
Through the example above , You can see that we didn't pass XML Method to inject attribute values , And by @Autowired Annotation implements automatic injection of attributes .

You can also apply annotations to methods with any name and multiple parameters , As shown in the following example :

public class MovieRecommender {

private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {

this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}

 Insert picture description here
 Insert picture description here
 Insert picture description here
You can also change @Autowired Apply to field , Even mix it with constructors , As shown in the following example :

public class MovieRecommender {

private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {

this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}

Make sure your target components ( for example ,MovieCatalog or CustomerPreferenceDao) Used by you for @Autowired Annotation injection point type consistent declaration . otherwise , Injection may be due to runtime “ No type match found ” Wrong and fail .

For those found by classpath scanning XML Defined bean Or component class , Containers usually know the specific type in advance . however , about @Bean Factory method , You need to ensure that the declared return type is sufficiently expressive . For components that implement multiple interfaces or components that may be referenced by their implementation types , Consider declaring the most specific return type in your factory method ( At least with reference to your bean The injection point is as specific as that required ).

You can also use the @Autowired Annotations are added to fields or methods that require an array of this type to indicate Spring from ApplicationContext Provide all... Of a particular type bean, This is shown in the following example :

public class MovieRecommender {

@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}

 Insert picture description here
 Insert picture description here
 Insert picture description here
The same applies to typed collections , This is shown in the following example :

public class MovieRecommender {

private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {

this.movieCatalogs = movieCatalogs;
}
// ...
}

If you want items in an array or list to be sorted in a specific order , Your goal bean Can achieve org.springframework.core.Ordered Interface or use @Order Or the standard @Priority annotation . otherwise , Their order follows the corresponding target in the container bean Defined registration order .

You can at the target class level and @Bean Method statement @Order annotation , May be used for a single bean Definition ( Use the same... In multiple definitions bean Class ). @Order The value may affect the priority of the injection point , But please pay attention to , They do not affect the singleton startup sequence , This is made up of dependencies and @DependsOn Declare the orthogonality of the decision .

Please note that , standard javax.annotation.Priority Annotations in @Bean Level not available , Because it cannot declare on a method . Its semantics can be through @Order Value combination @Primary In each type of single bean Modeling on .

As long as the expected key type is a string , Even typed Map Instances can also be assembled automatically . The mapping value contains all of the expected types bean, The key contains the corresponding bean name , This is shown in the following example :

public class MovieRecommender {

private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {

this.movieCatalogs = movieCatalogs;
}
// ...
}

By default , When there are no matching candidates bean When available for a given injection point , Automatic assembly will fail . For declared arrays 、 Set or map , At least one matching element is required .

The default behavior is to treat annotated methods and fields as indicating the required dependencies . You can change this behavior , As shown in the following example , By marking unsatisfiable injection points as unnecessary ( namely , By way of @Autowired Medium required Property is set to false), Enables the framework to skip unsatisfiable injection points :

public class SimpleMovieLister {

private MovieFinder movieFinder;
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {

this.movieFinder = movieFinder;
}
// ...
}

If the dependencies of non essential methods ( Or one of its dependencies , If you have more than one parameter ) Unavailable , It will not be called at all . under these circumstances , Non mandatory fields will not be filled at all , Keep its default value .

Injected constructor and factory method parameters are a special case , Because of Spring The constructor parsing algorithm may potentially handle multiple constructors ,@Autowired Medium required Attributes have some different meanings . Constructor and factory method parameters are valid by default , But there are some special rules in the single constructor scenario , For example, if there is no match bean You can use , Multi element injection point ( Array 、 aggregate 、 mapping ) Resolve to an empty instance . This allows a common implementation pattern , All of these dependencies can be declared in a unique multi parameter constructor —— for example , Declare as No @Autowired A single public constructor for annotations .

Any given bean Class has only one constructor that can declare @Autowired And will required Property is set to true, Indicates when used as Spring bean Constructor for auto assembly when . therefore , If required Property retains its default value true, Can only be used @Autowired Annotate a single constructor . If multiple constructors declare annotations , They must all declare required=false Can be considered as a candidate for automatic assembly ( Be similar to XML Medium autowire=constructor). Will be selected by matching Spring In container bean Constructor that can satisfy the largest number of dependencies . If there is no candidate to meet , Then the main / Default constructor ( If there is ).
Similarly , If a class declares multiple constructors , But none of them @Autowired annotation , Then the main / Default constructor ( If there is ). If a class declares only one constructor, start , It will always be used , Even without notes . Please note that , Annotated constructors need not be public .

Recommended @Autowired Of required Property instead of setter Method deprecated @Required notes . take required Property is set to false Indicates that this attribute is not required for automatic assembly , If it cannot be assembled automatically , Then ignore the property . On the other hand ,@Required More powerful , Because it forces properties to be set in any way supported by the container , If no value is defined , The corresponding exception will be raised .

perhaps , You can Java 8 Of java.util.Optional Express the non essential nature of a particular dependency , As shown in the following example :

public class SimpleMovieLister {

@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {

...
}
}

from Spring Framework 5.0 Start , You can also use it @Nullable annotation ( Any type in any package — for example , come from JSR-305 Of javax.annotation.Nullable) Or just use Kotlin Built in empty security support :

public class SimpleMovieLister {

@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {

...
}
}

You can also @Autowired Interfaces for well-known resolvable dependencies :BeanFactory、ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher and MessageSource. These interfaces and their extensions ( for example ConfigurableApplicationContext or ResourcePatternResolver) Will resolve automatically , No special settings are required . The following example is automatic assembly ApplicationContext object :

public class MovieRecommender {

@Autowired
private ApplicationContext context;
public MovieRecommender() {

}
// ...
}

@Autowired、@Inject、@Value and @Resource Comments by Spring BeanPostProcessor Implement processing . This means you can't be in your own BeanPostProcessor or BeanFactoryPostProcessor type ( If there is ) Apply these annotations in . These types must use XML or Spring @Bean The method is explicit “ Connect ”.

Article reference :https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config

copyright:author[TyuIn],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/01/202201261112525866.html