Mybatis-Spring(1)

The Mapper will Mybatis registered to Spring's ApplicationContext in a Spring life cycle management.

Mapper scanned for annotations usage

@Configuration
@MapperScan("org.mybatis.spring.sample.mapper")

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
public @interface MapperScan

Here, it is noted @MapperScan which wraps a comment: @Import (MapperScannerRegistrar.class)

Link @Import treatment: AbstractApplicationContext.refresh ()

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
	............
	  try {
		............
		// Invoke factory processors registered as beans in the context.
		invokeBeanFactoryPostProcessors(beanFactory);
		............
	  }
	}
}

@Import parsing and BeanDefiniton registration link: ConfigurationClassPostProcessor.processConfigBeanDefinitions

/**
 * Build and validate a configuration model based on the registry of
 * {@link Configuration} classes.
 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
	//1、所有的BeanDefiniton的name
	String[] candidateNames = registry.getBeanDefinitionNames();

	for (String beanName : candidateNames) {
		............
		//2、将所有的@Configuration的类放入configCandidates中
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}
	............ 
	the Set <BeanDefinitionHolder> a LinkedHashSet candidates in a new new = <BeanDefinitionHolder> (configCandidates); 
	do { 
		//. 3, which renders all classes @Configuration all annotations (@ Bean, @ Profile, Import @, ImportResource @, @ ComponentScan, Lazy @, @ PropertySource) 
		parser.parse (candidates in a); 
		............ 
          the Set <ConfigurationClass> = new new configClasses a LinkedHashSet <ConfigurationClass> (parser.getConfigurationClasses ( )); ............ // 4, by which resolution configClasses, all arranged converted to the BeanDefinition this.reader.loadBeanDefinitions (configClasses); ......... ... } the while (candidates.isEmpty ()!); ............ }

 

Here we look at what things do MapperScannerRegistrar

registerBeanDefinitions: Registration Bean

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

	// MapperScan配置的注解数据
    AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

    Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
    if (!Annotation.class.equals(annotationClass)) {
	  // 设置需要注册的annotationClass
      scanner.setAnnotationClass(annotationClass);
    }
    Class<?> markerInterface = annoAttrs.getClass("markerInterface");
    if (!Class.class.equals(markerInterface)) {
      // 设置需要注册的markerInterface
	  scanner.setMarkerInterface(markerInterface);
    }

    Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
    if (!BeanNameGenerator.class.equals(generatorClass)) {
      // 设置自定义的BeanNameGenerator
	  scanner.setBeanNameGenerator(BeanUtils.instantiateClass(generatorClass));
    }

    Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
    if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
      // 设置自定义的MapperFactoryBean.class
	  scanner.setMapperFactoryBean(BeanUtils.instantiateClass(mapperFactoryBeanClass));
    }
	// 设置sqlSessionTemplateRef的值到sqlSessionTemplateBeanName
    scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));
	// 设置sqlSessionTemplateRef的值到sqlSessionFactoryBeanName
    scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));

    List<String> basePackages = new ArrayList<String>();
    for (String pkg : annoAttrs.getStringArray("value")) {
      if (StringUtils.hasText(pkg)) {
        // 设置basePackages
		basePackages.add(pkg);
      }
    }
    for (String pkg : annoAttrs.getStringArray("basePackages")) {
      if (StringUtils.hasText(pkg)) {
        // 设置basePackages
		basePackages.add(pkg);
      } 
    }
    For (<?> Class clazz: annoAttrs.getClassArray ( "basePackageClasses")) { 
      // set basePackages 
	  basePackages.add (ClassUtils.getPackageName (clazz)); 
    } 
	// The annotationClass and markerInterface, provided addIncludeFilter 
    scanner.registerFilters () ; 
	// start scanning 
    scanner.doScan (StringUtils.toStringArray (basePackages)); 
  }

scanner.doScan: Scan

@Override 
public the Set <BeanDefinitionHolder> the doScan (String basePackages ...) { 
    // call ClassPathBeanDefinitionScanner.doScan, all classes are registered under the package into a container 
    the Set <BeanDefinitionHolder> BeanDefinitions = super.doScan (basePackages); 
    IF (BeanDefinitions .isEmpty ()) { 
        logger.warn ( "No MyBatis Mapper WAS found in '" + of Arrays.toString (basePackages) + "' Please Check your Package Configuration.."); 
    } the else { 
	// to beanDefinitions information 1, these interfaces allow the dynamic proxy classes MapperFactoryBean 2 may be provided corresponding to the proxy object SqlSession in 
        processBeanDefinitions (BeanDefinitions); 
    } 
    return BeanDefinitions; 
}

processBeanDefinitions: processing BeanDefiniton

void processBeanDefinitions Private (the Set <BeanDefinitionHolder> BeanDefinitions) { 
    GenericBeanDefinition Definition; 
    for: (BeanDefinitionHolder Holder BeanDefinitions) { 
		holder.getBeanDefinition Definition = (GenericBeanDefinition) (); 
		........... 
		// The interface IS Mapper the class of the bean Original the 
		// But, the Actual the class of the bean MapperFactoryBean iS 
		// constructor is provided as the interface into the parameters, see later MapperFactoryBean constructor, which is able to understand why in the 
		definition.getConstructorArgumentValues (). addGenericArgumentValue (definition.getBeanClassName ()); // Issue # 59 
		// Mapper will MapperFactoryBean.class as a class, is to make Sprintg perception, the Bean instance is to be created by defining the FactoryBean 
		definition.setBeanClass (the this. mapperFactoryBean.getClass ());
		........... 
		// set to run when the bean reference sqlSessionFactoryBeanName (sqlSessionFactoryRef value) is 
		definition.getPropertyValues () the Add ( "SqlSessionFactory", new new RuntimeBeanReference (this.sqlSessionFactoryBeanName));. 
		// set sqlSessionTemplateBeanName bean reference (value of sqlSessionTemplateRef) runtime 
		definition.getPropertyValues () the Add ( "SqlSessionTemplate", new new RuntimeBeanReference (this.sqlSessionTemplateBeanName));. 
        ........... 
    } 
}

  

 

Guess you like

Origin www.cnblogs.com/sleepingDogs/p/11085436.html