TyuIn 2022-01-26 11:12:58 阅读数:894
Follow up with a blog :https://blog.csdn.net/qq_43605444/article/details/121954378?spm=1001.2014.3001.5502
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.
@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
fromSpring Framework 5.1
Start Formal abandonment , In favor of using constructor injection to make the required settings ( orInitializingBean.afterPropertiesSet()
Custom implementation or customization of @PostConstruct Methods and bean Property setter method ).
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 .
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;
}
// ...
}
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;
}
// ...
}
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;
// ...
}
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 Mediumautowire=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 bySpring 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