MYBAITS3 Source Analysis (ii): Scan mapper associated to spring IOC container

Source: Internet
Author: User

First, tell me how mapper is from the configuration to the object.

<!--create mapper beans with automatic scanning (single update mode)--  <bean class= "Org.mybatis.spring.mapper.MapperScannerConfigurer ">      <property name=" basepackage "value=" Com.xxx.dao "/> <property name=      " Sqlsessiontemplatebeanname "value=" Sqlsessiontemplatesimple "/>      <property name=" MarkerInterface "value=" Com.xxx.dao.SimpleDao "/>  </bean>  

Implemented Basepackage all interfaces that implement MARKERINTERFACE-specified classes will be scanned for parsing. Mapperscannerconfigurer implements the Beandefinitionregistrypostprocessor (Beandefinitionregistry back processor, think of the spring AOP) interface, The Postprocessbeandefinitionregistry method that enables it to invoke all beandefinition after the Spring ApplicationContext container has registered it. Let's see how mapperscannerconfigurer is implementing this method.

public void Postprocessbeandefinitionregistry (Beandefinitionregistry registry) throws Beansexception {if (this.proces Spropertyplaceholders) {//Handle some of the mybaits related properties that are configured in the. Properties, such as Sqlsessionfactorybeanname Processpropertyplaceholde    RS ();    }//Create Classpath scanner Classpathmapperscanner scanner = new Classpathmapperscanner (registry);    Define the scan rule scanner.setaddtoconfig (this.addtoconfig) According to the configuration for scanner;    Scanner.setannotationclass (This.annotationclass);    Scanner.setmarkerinterface (This.markerinterface);    Scanner.setsqlsessionfactory (this.sqlsessionfactory);    Scanner.setsqlsessiontemplate (this.sqlsessiontemplate);    Scanner.setsqlsessionfactorybeanname (This.sqlsessionfactorybeanname);    Scanner.setsqlsessiontemplatebeanname (This.sqlsessiontemplatebeanname);    Scanner.setresourceloader (This.applicationcontext);    Scanner.setbeannamegenerator (This.namegenerator);    Scanner.registerfilters (); The Tokenizetostringarray function used in the parameter to handle multiple basepackage is usually ";" Separated Scanner.scan(Stringutils.tokenizetostringarray (This.basepackage, Configurableapplicationcontext.config_location_delimiters)  ); }
     the Doscan function of the parent class of the Classpathmapperscanner class Classpathbeandefinitionscanner:
Protected set<beandefinitionholder> Doscan (String ... basepackages) {assert.notempty (basepackages, "at least one Base package must is specified "),//beandefinitionholder container set<beandefinitionholder> beandefinitions = new Linkedhashset<beandefinitionholder> (); for (String basepackage:basepackages) {//Select candidate Set<beandefinition > candidates = findcandidatecomponents (basepackage); for (Beandefinition candidate:candidates) {ScopeMetadata Scopemetadata = This.scopeMetadataResolver.resolveScopeMetadata (candidate); Candidate.setscope ( Scopemetadata.getscopename ()); String beanname = this.beanNameGenerator.generateBeanName (candidate, this.registry);//If it is an abstract class under the base package, We configure the Mapper interface if it is not annotated way also will go this processing if (candidate instanceof abstractbeandefinition) {postprocessbeandefinition ( abstractbeandefinition) candidate, beanname);} If the class under the base package is annotated if (candidate instanceof annotatedbeandefinition) { Annotationconfigutils.processcommondefinitionannotations ((annotatedbeandefinition) candidate);} If DAO package (aBasepakage is this) the class under Mybaits is required to register its beandefinitionif with the Spring IOC container (checkcandidate (Beanname, candidate)) { Beandefinitionholder Definitionholder = new Beandefinitionholder (candidate, beanname);d Efinitionholder = Annotationconfigutils.applyscopedproxymode (Scopemetadata, Definitionholder, this.registry); BeanDefinitions.add ( Definitionholder); Registerbeandefinition (Definitionholder, This.registry);}} return beandefinitions;}
Classpathmapperscanner's Doscan function:
Public set<beandefinitionholder> Doscan (String ... basepackages) {//Call parent class scan function set<beandefinitionholder> be    Andefinitions = Super.doscan (basepackages); if (Beandefinitions.isempty ()) {Logger.warn ("No MyBatis Mapper is found in '" + arrays.tostring (basepackages) + "' Package. Please check your configuration. "); else {for (Beandefinitionholder holder:beandefinitions) {genericbeandefinition definition = (genericbeande        finition) holder.getbeandefinition (); The mapperinterface here is that we write the Mapper interface is generally an empty interface, actually associated to it//the beandefinition in the Bean is Mapperfactorybean,        Mapperfactorybean is important definition.getpropertyvalues (). Add ("Mapperinterface", Definition.getbeanclassname ());        Definition.setbeanclass (Mapperfactorybean.class);        Definition.getpropertyvalues (). Add ("Addtoconfig", this.addtoconfig);        Boolean explicitfactoryused = false; if (Stringutils.hastext (This.sqlsessionfactorybeanname)) {definition.getpropertyvalues(). Add ("Sqlsessionfactory", New Runtimebeanreference (This.sqlsessionfactorybeanname));        Explicitfactoryused = true; } else if (this.sqlsessionfactory! = null) {definition.getpropertyvalues (). Add ("Sqlsessionfactory", this.sqlsess          Ionfactory);        Explicitfactoryused = true; } if (Stringutils.hastext (this.sqlsessiontemplatebeanname)) {if (explicitfactoryused) {Logger . Warn ("Cannot use Both:sqlsessiontemplate and sqlsessionfactory together.          Sqlsessionfactory is ignored. "); Definition.getpropertyvalues (). Add ("Sqlsessiontemplate", New Runtimebeanreference (          This.sqlsessiontemplatebeanname));        Explicitfactoryused = true;  } else if (this.sqlsessiontemplate! = null) {if (explicitfactoryused) {Logger.warn ("Cannot use both: Sqlsessiontemplate and Sqlsessionfactory together.          Sqlsessionfactory is ignored. "); Definition.getpropertyvalues (). Add ("SqlsessiontemplaTE ", this.sqlsessiontemplate);        Explicitfactoryused = true;  } if (!explicitfactoryused) {if (logger.isdebugenabled ()) {Logger.debug ("Enabling Autowire by          Type for Mapperfactorybean with Name ' "+ holder.getbeanname () +" '. ");        Definition.setautowiremode (Abstractbeandefinition.autowire_by_type);  }}} return beandefinitions; }

Protected Boolean checkcandidate (String beanname, Beandefinition beandefinition) throws IllegalStateException {// If spring does not register the beanname corresponding Bean then it is the class mybaits needs, the general Mybaits Mapper class is that an interface will not be loaded into the IOC container by spring instantiation if (! This.registry.containsBeanDefinition (Beanname)) {return true;} If spring has a bean of this class defined beandefinition Existingdef = this.registry.getBeanDefinition (beanname); Beandefinition originatingdef = Existingdef.getoriginatingbeandefinition (); if (originatingdef! = null) {ExistingDef = Originatingdef;} If this class is repeatedly scanned, or if the source files of the same class are repeatedly fetched or subclasses of other classes are incompatible, such classes are not compliant with mybaits loading requirements to return Falseif (Iscompatible (beandefinition, Existingdef ) {return false;} throw new Conflictingbeandefinitionexception ("Annotation-specified bean name '" + beanname + "' For Bean class [" + Beandef Inition.getbeanclassname () + "] conflicts with existing," + "non-compatible bean definition of same name and class [" + EX Istingdef.getbeanclassname () + "]");}

Let's take a look at the Checkdaoconfig function of Mapperfactorybean to see how it relates the DAO to the corresponding Mapper.xml:

protected void Checkdaoconfig () {//Call the parent class with the same name Method    Super.checkdaoconfig ();    Gets the configuration file object in Java in Sqlsessionfactorybean config    //If there is no mapperinterface definition, add the definition of this mapper/    / This configuration object is not spring under the mybaits!    Configuration Configuration = Getsqlsession (). GetConfiguration ();    if (This.addtoconfig &&!configuration.hasmapper (this.mapperinterface)) {      try {        Configuration.addmapper (This.mapperinterface);      } catch (Throwable t) {        logger.error ("error while adding the mapper '" + this.mapperinterface + "' to configuration.", T );        throw new IllegalArgumentException (t);      } finally {        errorcontext.instance (). reset ();}}}  

This mapper interface is registered to the sqlsession, each time the operation Sqlsession will be based on this mapperinterface to find the corresponding Mapper.xml build mapper to complete the database operation.

After the above process Mybaits found all the mapper and loaded it into the spring IOC container, this chapter is finished. In the next chapter, we'll talk about how mybaits resolves Mapper.xml.





MYBAITS3 Source Analysis (ii): Scan mapper associated to spring IOC container

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.