Starting with Spring3.0, a new way to configure Bean definition is added, which is to configure Bean definition through Java Code.
The difference between XML and annotation two configuration methods is that:
The first two types of XML and Annotation are configured in a predefined way, that is, after developers have pre-defined the various properties of the bean through an XML file or Annotation, the spring container will first parse the configuration properties and generate the corresponding one. Bean Definition, loaded into the property container of the Defaultlistablebeanfactory object. At the same time, the Spring framework defines some of the bean definitions that are used internally, such as the bean named " Org.springframework.context.annotation.internalConfigurationAnnotationProcessor "of Configurationclasspostprocessor definition.
The spring framework filters out the bean definitions of the Beandefinitionregistrypostprocessor type based on the first two configurations, and then does not do any definition parsing actions for the bean definition, and the spring The framework generates its corresponding Bean object (such as a configurationclasspostprocessor instance). In conjunction with spring context Source, it is known that this object is a processor type tool class, and the spring container invokes the processor's postprocessbeandefinitionregistry before instantiating the developer-defined Bean. (...) Method. The implementation of Java Code configuration bean definition-based processing is implemented here.
Sequence diagram for parsing beans based on Java Code (view larger image)
This map is for everyone to know, and here is not a detailed explanation.
Based on the Java Code configuration, its implementation differs from the first two. It is after the Spring framework has parsed the XML-based and Annotation configuration, by joining the Beandefinitionregistrypostprocessor type of processor to process configuration information, allowing developers to programmatically Defines a Java object. The advantage is that the configuration information can be concentrated in a certain number of Java objects, while Java programming is more flexible than the Annotation-based approach. And this configuration gives developers a very good example of how to add user-defined parsing tool classes. Its main disadvantage is that the combination of Java code, configuration information changes need to recompile Java code, in addition, this is a new method of parsing, the need for a certain learning cost.
Another point to mention is that the spring framework has 3 main hooks, namely:
Org.springframework.context.ApplicationContextAware
Its Setapplicationcontext method is called the first one before spring starts. We used to start the Jdon framework at the same time.
Org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
Its postprocessbeandefinitionregistry and Postprocessbeanfactory methods are called second and third, and they are started before the bean initialization is created. If spring's bean requires components from other third parties, we'll inject it here to spring.
Org.springframework.context.ApplicationListener
Used to do something after initialization, when the bean for all XML or meta annotations in spring starts to be created successfully, the only way to invoke it is onapplicationevent.
Let's complete one by creating a bean from Java code and registering it for spring management.
In this example, we create an interface, then create 2 implementation classes of the interface, name different names, and then use @qualifier to specify the injected instance where it needs to be injected.
1, Interface Shanhy.java
package org.springboot.sample.config;publicinterface Shanhy { void display();}
2. Realizing class Shanhya.java
package org.springboot.sample.config;publicclass ShanhyA implements Shanhy { @Override publicvoiddisplay() { System.out.println("AAAAAAAAAAAA"); }}
3. Realizing class Shanhyb.java
package org.springboot.sample.config;publicclass ShanhyB implements Shanhy { @Override publicvoiddisplay() { System.out.println("BBBBBBBBBBBB"); }}
4, define the implementation of interface Beandefinitionregistrypostprocessor
package Org. Springboot. Sample. config;import org. SLF4j. Logger;import org. SLF4j. Loggerfactory;import org. Springframework. Beans. Beansexception;import org. Springframework. Beans. Factory. Annotation. Annotatedgenericbeandefinition;import org. Springframework. Beans. Factory. config. Beandefinitionholder;import org. Springframework. Beans. Factory. config. Configurablelistablebeanfactory;import org. Springframework. Beans. Factory. Support. Beandefinitionreaderutils;import org. Springframework. Beans. Factory. Support. Beandefinitionregistry;import org. Springframework. Beans. Factory. Support. Beandefinitionregistrypostprocessor;import org. Springframework. Beans. Factory. Support. Beannamegenerator;import org. Springframework. Context. Annotation. Annotationbeannamegenerator;import org. Springframework. Context. Annotation. Annotationconfigutils;import org. Springframework. Context. Annotation. Annotationscopemetadataresolver;import org. Springframework. Context. Annotation. Configuration;import org. Springframework. Context. Annotation. Scopemetadata;import org. Springframework. Context. Annotation. Scopemetadataresolver;/** * Implements itself to instantiate beans and register as spring management * * @author Tan Hongyu (365384722) * @myblog http://blog.csdn.net/catoop/* @create 2016 January 21 * /@Configurationpublic class Mybeandefinitionregistrypostprocessor implements Beandefinitionregistrypostprocessor { private static final Logger Logger = loggerfactory. GetLogger(Mybeandefinitionregistrypostprocessor. Class);Private Scopemetadataresolver Scopemetadataresolver = new Annotationscopemetadataresolver ();Private Beannamegenerator Beannamegenerator = new Annotationbeannamegenerator ();@Override public void Postprocessbeanfactory (Configurablelistablebeanfactory beanfactory) throws Beansexception { Logger. Info("Invoke metho postprocessbeanfactory");} @Override public void Postprocessbeandefinitionregistry (Beandefinitionregistry registry) throws Beansexception { Logger. Info("Invoke metho postprocessbeandefinitionregistry");Registerbean (Registry,"Shanhya", Shanhya. Class);Registerbean (Registry,"Shanhyb", Shanhyb. Class);} private void Registerbean (Beandefinitionregistry registry, String name, class<?> beanclass) {Annotatedge Nericbeandefinition abd = new Annotatedgenericbeandefinition (beanclass);Scopemetadata Scopemetadata = This. Scopemetadataresolver. Resolvescopemetadata(ABD);Abd. Setscope(Scopemetadata. Getscopename());You can automatically generate the name String Beanname = (name! = null? name:this. Beannamegenerator. Generatebeanname(Abd, Registry));Annotationconfigutils. Processcommondefinitionannotations(ABD);Beandefinitionholder Definitionholder = new Beandefinitionholder (ABD, Beanname);Beandefinitionreaderutils. Registerbeandefinition(Definitionholder, Registry);}}
5. Use test
As usual can be injected directly into our object, for the same interface we need to specify the name
/** * Test parameter injection * * @author Tan Hongyu (365384722) * @myblog http://blog.csdn.net/catoop/* @create January 13, 2016 */ @Configuration public class myconfiguration { @Bean public Filterregistrationbean filterregistrationbean (@ Qualifier ("Shanhyb") Shanhy shanhy) {Filterregistrationbean filterregistration = new Filterregistrationbean (); Shanhy.display (); //ellipsis code return filterregistration; }}
Using @resource or @Autowired and specifying @qualifier can also
@RestController@RequestMapping("/hello")publicclass HelloController { @Resource(name="shanhyA") private Shanhy shanhyA; @Autowired @Qualifier("shanhyB") private Shanhy shanhyB; // 省略代码}
Here is a bit of experience to say, in @Configuration, can not be injected with the injection of attributes, can only be injected by the way of parameters, the reason is that the @configuration class begins to be loaded, at this time you want to do property injection, The Bean object that needs to be injected doesn't exist yet.
In the next article, we'll use this approach to dynamically create MyBatis-based multi-data sources.
Spring Boot uses Java code to create a bean and register it in spring