mybatis-Spring ClassPathMapperScanner源码分析(自定义注解加载Bean)

用人话讲明白线性回归LinearRegression 目录 什么是回归 一元线性回归 损失函数 最小二乘估计 小结 1. 什么是回归 当我们学习一门新课程、接触一个新专业时,总会对该领域的专有名词感到困惑,甚至看完解释仍难以理解其含义。在我们一起学习machine learning的过程中,我会尽量对相关名词用“人话”做一遍解释,以减少学习的“痛苦感”。 譬如今天要学的线性“回归”,这个回归(regression)和我们平时说的“回归祖国”的回... 阅读详情

摘要:

在使用mybatis时,可以通过mybatis-spring的MapperFactoryBean来配置一系列的DAO接口,MapperFactoryBean的getObject方法能返回DAO接口对应的动态代理类,实际是通过DefaultSqlSession以动态代理的方式生成DAO接口的实现类。而当DAO类很多时,可以通过mybatis-spring的MapperCannerConfigurer类配置要描述的包,来实现生成MapperFactoryBean对象,减少配置。

一、MapperFactoryBean 与MapperCannerConfigurer 配置回顾

MapperFactoryBean 配置要使用的DAO
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">  
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />  
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />  
</bean>  
通过上面的配置在 Service层中就可以直接注入 userMapper这个DAO,MapperFactoryBean内部会调用DefaultSqlSession以动态代理的方式生成DAO接口的实现类。

MapperCannerConfigurer配置多个要使用的DAO
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
  <property name="basePackage" value="org.mybatis.spring.sample.mapper" />  
  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>  

通过上面的配置在包org.mybaits.spring.sample.mapper中下面对应的DAO接口,便能生成对应的MapperFactoryBean对象,然后被Service层调用。因为在DefaultSqlSession
内部是以动态代理的方式生成DAO接口对应的实现类,这里DAO要声明为接口。
MapperCannerConfigurer是通过实现BeanDefinitionRegistryPostProcessor接口,完成对BeanDefinitionRegistry自定义与修改,postProcessBeanDefinitionRegistry方法中则调用了ClassPathMapperScanner类。该类通过扫描包来指定
要生成的Bean。。。

二、ClassPathMapperScanner代码分析

ClassPathMapperScanner类实现了ClassPathBeanDefinitionScanner并对registerFilters方法与doScan方法进行了重写。
registerFilters方法主要是根据annotationClass或者是markerInterface属性来指定只扫描指定包下面的类带有某个注解的接口或者是为某个接口的子接口的接口。
public void registerFilters() {
    boolean acceptAllInterfaces = true;

    // if specified, use the given annotation and / or marker interface
    if (this.annotationClass != null) {
      addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
      acceptAllInterfaces = false;
    }

    // override AssignableTypeFilter to ignore matches on the actual marker interface
    if (this.markerInterface != null) {
      addIncludeFilter(new AssignableTypeFilter(this.markerInterface) {
        @Override
        protected boolean matchClassName(String className) {
          return false;
        }
      });
      acceptAllInterfaces = false;
    }

    if (acceptAllInterfaces) {
      // default include filter that accepts all classes
      addIncludeFilter(new TypeFilter() {
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
          return true;
        }
      });
    }

    // exclude package-info.java
    addExcludeFilter(new TypeFilter() {
      public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        String className = metadataReader.getClassMetadata().getClassName();
        return className.endsWith("package-info");
      }
    });
  }

doScan方法用来将包下面的接口转化为MapperFactoryBean的类。
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
    Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

    if (beanDefinitions.isEmpty()) {
      logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
    } else {
      for (BeanDefinitionHolder holder : beanDefinitions) {
        GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();

        if (logger.isDebugEnabled()) {
          logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() 
              + "' and '" + definition.getBeanClassName() + "' mapperInterface");
        }

        // the mapper interface is the original class of the bean
        // but, the actual class of the bean is MapperFactoryBean
        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.sqlSessionFactory);
          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;
  }

三、通过实现ClassPathBeanDefinitionScanner类自下定义bean注解的扫描

1、定义自己的注解

这里的注解并没有被@Component注解,而通过ClassPathBeanDefinitionScanner 类实现扫描。
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomizeComponent {
 String value() default "";
}

2、被注解的类

@CustomizeComponent
public class ScanClass1 {
public void print() {
    System.out.println("scanClass1");
}
}

3、自定义的BeanScannerConfigurer类

BeanScannerConfigurer用于嵌入到Spring的加载过程的中,这里用到了BeanFactoryPostProcessor 和 ApplicationContextAware。Spring提供了一些的接口使程序可以嵌入Spring的加载过程。这个类中的继承ApplicationContextAware接口,Spring会读取ApplicationContextAware类型的的JavaBean,并调用setApplicationContext(ApplicationContext applicationContext)传入Spring的applicationContext。
同样继承BeanFactoryPostProcessor接口,Spring会在BeanFactory的相关处理完成后调用postProcessBeanFactory方法,进行定制的功能。
@Component
public static class BeanScannerConfigurer implements  BeanFactoryPostProcessor, ApplicationContextAware {
	private ApplicationContext applicationContext;
	
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
	    this.applicationContext = applicationContext;
	}
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
	    Scanner scanner = new Scanner((BeanDefinitionRegistry) beanFactory);
	    scanner.setResourceLoader(this.applicationContext);
	    scanner.scan("org.wcong.test.spring.scan");
	}
}

4、ClassPathBeanDefinitionScanner实现类Scanner

Scanner继承的ClassPathBeanDefinitionScanner是Spring内置的Bean定义的扫描器。
includeFilter里定义了类的过滤器,newAnnotationTypeFilter(CustomizeComponent.class)表示只取被CustomizeComponent修饰的类。只扫描我们自已定义的注解。
doScan里扫面了包底下的读取到BeanDefinitionHolder,自定义GenericBeanDefinition相关功能。

public final static class Scanner extends ClassPathBeanDefinitionScanner {
	  public Scanner(BeanDefinitionRegistry registry) {
	      super(registry);
	  }
	  public void registerDefaultFilters() {
	      this.addIncludeFilter(new AnnotationTypeFilter(CustomizeComponent.class));
	  }
	  public Set<BeanDefinitionHolder> doScan(String... basePackages) {
	      Set<BeanDefinitionHolder> beanDefinitions =   super.doScan(basePackages);
	      for (BeanDefinitionHolder holder : beanDefinitions) {
	          GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
	          definition.getPropertyValues().add("innerClassName", definition.getBeanClassName());
	          definition.setBeanClass(FactoryBeanTest.class);
	      }
	      return beanDefinitions;
	  }
	  public boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
	     return super.isCandidateComponent(beanDefinition) && beanDefinition.getMetadata()
	.hasAnnotation(CustomizeComponent.class.getName());
	  }
}

5、得到我们Bean

FactoryBean是Spring中比较重要的一个类。它的描述如下

Interface to be implemented by objects used within a BeanFactory which are themselves factories. 
If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean* instance that will be exposed itself
普通的JavaBean是直接使用类的实例,但是如果一个Bean继承了这个借口,就可以通过getObject()方法来自定义实例的内容,在FactoryBeanTest的getObject()就通过代理了原始类的方法,自定义类的方法。
public static class FactoryBeanTest<T> implements InitializingBean, FactoryBean<T> {
	  private String innerClassName;
	  public void setInnerClassName(String innerClassName) {
	      this.innerClassName = innerClassName;
	  }
	  public T getObject() throws Exception {
	      Class innerClass = Class.forName(innerClassName);
	      if (innerClass.isInterface()) {
	          return (T) InterfaceProxy.newInstance(innerClass);
	      } else {
	          Enhancer enhancer = new Enhancer();
	          enhancer.setSuperclass(innerClass);
	          enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	          enhancer.setCallback(new MethodInterceptorImpl());
	          return (T) enhancer.create();
	      }
	  }
	  public Class<?> getObjectType() {
	      try {
	            return Class.forName(innerClassName);
	      } catch (ClassNotFoundException e) {
	            e.printStackTrace();
	      }
	      return null;
	  }
	  public boolean isSingleton() {
	      return true;
	  }
	  public void afterPropertiesSet() throws Exception {
      }
}
public static class InterfaceProxy implements InvocationHandler {
	  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	      System.out.println("ObjectProxy execute:" + method.getName());
	      return method.invoke(proxy, args);
	  }
	  public static <T> T newInstance(Class<T> innerInterface) {
	      ClassLoader classLoader = innerInterface.getClassLoader();
	      Class[] interfaces = new Class[] { innerInterface };
	      InterfaceProxy proxy = new InterfaceProxy();
	      return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
	  }
}
public static class MethodInterceptorImpl implements MethodInterceptor {
      public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
	      System.out.println("MethodInterceptorImpl:" + method.getName());
	      return methodProxy.invokeSuper(o, objects);
      }
}

6、main函数

@Configuration
public class CustomizeScanTest {
   public static void main(String[] args) {
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new        AnnotationConfigApplicationContext();                
    annotationConfigApplicationContext.register(CustomizeScanTest.class);
    annotationConfigApplicationContext.refresh();
    ScanClass1 injectClass = annotationConfigApplicationContext.getBean(ScanClass1.class);
    injectClass.print();
   }
}
详解代码见https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/spring/CustomizeScanTest.java

YOLOv11改进 | 损失函数改进篇 | 2024最新高质量的目标检测边界框回归损失Unified-IoU、FocalUIoU、FocalInvUIoU(设置动态epoch参数) 本文给大家带来的改进机制是最近新提出的高质量的目标检测边界框回归损失,其通过动态调整模型对不同质量预测框的关注,优化目标检测中的边界框回归精度。UIoU引入了FocalBox方法,通过缩放预测框与真实框分配权重,并采用了退火策略(引入动态参数epoch),逐渐将模型的注意力从低质量预测框转移到高质量预测框,平衡了训练速度与检测精度。其还有一定的解决样本不平衡问题,同时该损失函数可以和现有的任何边界框回归损失函数进行结合,例如ShapeIoU和其结合可以形成二次创新,它是一种类似于之前的Inner的机制. 阅读详情

相关推荐

用Omniverse Kit开发第一个USD插件:从环境配置到实战案例(Python 3.7版)

本文详细介绍了如何使用NVIDIA Omniverse Kit和Python 3.7开发第一个USD插件,涵盖从环境配置到实战案例的全过程。通过创建可实时同步材质属性的USD插件,开发者可以快速掌握Omniverse开发框架,提升3D内容创作效率。

x8y9z0的博客 586

mapper扫描,自动装配

自动装配是springboot的一大特点 关键类: 1、MapperScannerConfigurer 2、ClassPathMapperScanner 类定义及图 MapperScannerConfigurer public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware

才子佳人的博客 1398

TM1650数码管驱动芯片

简介 TM1650是一款国产4位共阴数码管驱动芯片,它还带有矩阵按键扫码功能。它的基本参数如下: 工作电压:3~5V 数码管驱动模式:8段x4位共阴数码管 矩阵按键驱动模式:7x4矩阵按键,不支持组合键 通信接口:类IIC,使用了IIC相同的时序,但没有完全遵守IIC的协议,不带从机地址 引脚定义 SCL:串行通信时钟线 SDA:串行通信数据线 做数码管驱动使用时 DIGx:数码管的位选引脚,灌电流驱动,最大可吸收150mA电流 A~DP:数码管的段驱动引脚,拉电流驱动,最大可输出25m

luliplus的博客 4万+

org.mybatis.spring.mapper.ClassPathMapperScanner和tk.mybatis.spring.annotation.MapperScan

org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.xxx.xxx.xxx]' package. Please check your configuration.

qq_42553504的博客 1625

ARM CoreSight架构

CoreSight架构是现代复杂SoC的“飞行数据记录仪”(黑匣子)和“精密诊断仪”的结合体。它彻底改变了嵌入式系统的调试方式,从传统的“盲人摸象”变成了拥有“上帝视角”,是ARM生态系统能够支撑起从微控制器到高性能服务器芯片如此广泛产品线的重要基石技术之一。

guigenyi的专栏 1421

电池保护板为什么采用NTC热敏电阻而不是PTC热敏电阻?

R25=10K,即环境温度25°时,阻值是10K),温度变化1°C,阻值相应地明显变化,温度响应很灵敏,也就能精准地反向换算出阻值对应的温度。另外,还有功率型NTC热敏电阻,其主要用在开关电源设计中,串联在市电输入上,抑制浪涌电流。电池保护板上的NTC热敏电阻(NTC一端接地,另一端接电池充电控制IC管脚),在电池温度上升时,NTC热敏电阻温度也会随之上升,从而NTC电阻值会下降,因此电池充电控制IC用ADC检测的电压值就降低,当检测到的电压值达到下限阈值时,电池充电控制IC就会停止对电池的充电或放电。

电子绿洲的博客 5626

mybatis与spring的整合之ClassPathMapperScanner

mybatis与spring的整合之ClassPathMapperScannerjava配置应用配置类源码分析@MapperScanMapperScannerRegistrar.registerBeanDefinitionsClassPathMapperScanner.doScan父类ClassPathBeanDefinitionScanner.doScan扫描注册bdprocessBeanDef...

yu_kang的博客 1万+

神经影像和人类基因组关联分析的实践过程

现代全脑转录图谱为研究脑组织的分子相关性提供了前所未有的机会,可以使用无创神经成像进行量化。然而,将神经影像学数据与转录组测量相结合并不是直截了当的,需要仔细考虑才能做出有效的推断。在本文中,我们回顾了最近的研究工作,探讨了不同的方法选择如何影响成像转录组学分析的三个主要阶段,包括1)转录图谱数据的处理;2)将转录测量与独立衍生的神经影像学表型相关联;3)通过基因富集分析评估鉴定的关联的功能意义。我们的目标是为这个快速发展的领域促进标准化和可复制方法的发展。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 2201

MyBatis入门系列(25) -MyBatis-Spring核心之@MapperScan使用及源码分析

注册映射器 在使用Mybatis中,我们需要将Mapper接口注册到Spring中,这叫注册映射器。 注册映射器的方法根据你的配置方法,即经典的 XML 配置或新的 3.0 以上版本的 Java 配置(也就是常说的 @Configuration),而有所不同。 XML 配置 在你的 XML 中加入 MapperFactoryBean 以便将映射器注册到 Spring 中。就像下面一样: <bean id="userMapper" class="org.mybatis.spring.mapper.Map

记录知识、锤炼自我 7760

OpenClaw实战四|内容创作全流程AI助理:自动撰稿+智能剪辑+多平台发布,一人顶一个内容团队

AI替代的是「写稿、剪辑、发布」这种流水线工作,真正让你解放出来,去做选题、创意、人设、变现这些高价值的事。OpenClaw这套内容创作全流程AI助理,最大的价值不是「帮你发内容」,而是让一个人,拥有一个内容团队的产能。不管是个人博主、小团队,还是企业新媒体,都能用零代码的方式,快速搭建属于自己的自动化内容矩阵。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 589

在ubuntu20.04中安装MATLAB时常见问题及解决方法

   如果你刚装完ubuntu20.04,这时你想要安装MATLAB2021A,在输入命令./install进行安装时,可能会报以下错误:    terminate called after throwing an instance of ‘JailContainerException’ what(): Error: 88: No JRE version parsed from/media/jzx/MATHWORKS_R2021A/sys /java/jre/glnxa64/jre/release   

慕羽★的博客 1万+

MyBatis-Spring核心之MapperScan使用及源码分析

在使用Mybatis中,我们需要将Mapper接口注册到Spring中,这叫注册映射器。注册映射器的方法根据你的配置方法,即经典的 XML 配置或新的 3.0 以上版本的 Java 配置(也就是常说的 @Configuration),而有所不同。

Roy0826的博客 9164

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

MyBatis-Spring Mapper自动扫描机制揭秘:@MapperScan注解的完整使用手册

🚀 **快速掌握MyBatis-Spring集成框架中最重要的自动配置神器!** 在Spring Boot和MyBatis集成的开发中,`@MapperScan`注解是实现Mapper自动注册的终极利器。通过本文,你将彻底理解这个强大注解的工作原理和最佳实践。💡 MyBatis-Spring集成框架中的`@MapperScan`注解是Spring 3.1+环境下配置MyBatis映射器的首选

gitblog_00994的博客 661

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

MyBatis 整合Spring解析 【侧重mapper怎么变成bean】

基于spring提供的接口,ImportBeanDefinitionRegistrar 接口介绍: ImportBeanDefinitionRegistrar类只能通过其他类@Import的方式来加载,通常是启动类或配置类。(在mybatis 通过Mapper Scan 注解实现) 使用@Import,如果括号中的类是ImportBeanDefinitionRegistrar的实现类,则会调用接口方法,将其中要注册的类注册成bean。 实现该接口的类拥有注册bean的能力。 官方说明: /** .

Heihei 's note 1176

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

使用MyBatis时为什么Dao层不需要@Repository

问题Service层注入Dao时, Intellij 总会以红色波浪线提示我们 12@Autowiredprivate UserDao userDao; Could not autowire. No beans of ‘UserDao’ type found.Checks autowiring problems in a bean class. 尽管我...

hehyyoulan的博客 6383

@Repository与@Mapper

问题 Service层注入Dao时, Intellij 总会以红色波浪线提示我们 @Autowired private UserDao userDao; Could not autowire. No beans of ‘UserDao’ type found. Checks autowiring problems in a bean class. 尽管我们都知道 Dao 层的 Bean 实际上都是有的,并且可以设置关闭这恼人的提示,但是我们有没有想过为什么 Intellij 就找不到这个 Bean 呢?甚

Ryze 505

mybatis plus 按月的数据_深入理解Mybatis解析Mapper底层原理

背景最近在使用高版本Spring Boot 2.x整合mybatis-plus 3.4.1时,控制台出现大量的warn提示XxxMapper重复定义信息:Bean already defined with the same name。2020-12-0719:37:26.025WARN25756---[main]o.m.s.mapper.ClassPa...

weixin_39819671的博客 710

Mybatis的Mapper扫描机制:@MapperScan源码

通过@Import注解导入了MapperScannerRegistrarMapperScannerRegistrar向容器中注入是一个BeanDefinitionRegistryPostProcessor,将会被Spring容器回调方法在方法中创建了,并且调用ClassPathMapperScanner的scan方法重写了父类ClassPathBeanDefinitionScanner的doScan方法,在扫描完Bean获取到BeanDefinition后,在方法对其进行了额外的处理。

zzzj的博客 9259

ClassPathMapperScanner具体是如何工作的?

注解配置:首先,开发者在配置类上使用注解指定要扫描的包路径。初始化与配置:当 Spring 应用上下文启动时,作为的实现,在 Spring 上下文刷新之前处理注解,初始化并配置。扫描过程根据配置的包路径扫描这些包及其子包,查找所有符合要求的组件(即 Mapper 接口)。注册 Bean:对于找到的每个 Mapper 接口,创建相应的并将其注册到 Spring 容器中。自动扫描自动扫描指定包路径下的 Mapper 接口。灵活配置:支持通过注解或接口类型过滤扫描结果。动态代理:利用。

Java的专栏 419

浅入浅出Mybatis:(二)Mapper interface加载过程

前言 在上一篇中,我们对MyBatis的整体项目结构进行了大览,本篇,开始正式进入源码分析的第一篇,来一起了解一下MyBatis的mapper interface与XML配置文件的加载过程。 本篇源代码基于SpringBoot 1.5x,Mybatis-spring 1.3x、Mybatis 3.4x。 SpringBoot加载MyBaits的过程 在Spring项目中,我们对Mybatis进行配...

wtopps的专栏 4796

基于MapperScan注解的Mybatis动态代理加载机制

1.在springboot项目通过MapperScan注解方式,扫描dao,并通过动态代理的方式。 /** * 程序注解配置 * * @author ruoyi */ @Configuration // 表示通过aop框架暴露该代理对象,AopContext能够访问 @EnableAspectJAutoProxy(exposeProxy = true) // 指定要扫描的Mapper类的包的路径 @MapperScan("com.ruoyi.**.mapper") public class Ap

xl649138628的专栏 1438

spring集成Mybatis学习三种方式扫描加载mapper接口

@MapperCan @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(MapperScannerRegistrar.class) public @interface MapperScan { /** * Alias for the {@link #basePackages()} attribute. Allows for more concise * annotatio.

qq_41665121的博客 2701

ClassPathMapperScanner 重写了 isCandidateComponent 方法

ClassPathMapperScanner 重写了 isCandidateComponent 方法

u014244856的博客 391

mybatis-spring注解MapperScan的原理

很多开发者应该都知道,我们只使用@MapperScan这个注解就可以把我们写的Mybatis的Mapper接口加载到Spring的容器中,不需要对每个Mapper接口加@Mapper这个注解了,加快了我们开发的效率。

接需求(Java),各个平台都同名,欢迎搜索关注 970

@MapperScan源码解析

MapperScan以@Import为切入点的注入一个类型为MapperScannerConfigurer的BeanDefinitionMapperScannerConfigurer继承BeanDefinitionRegistryPostProcessor接口,在某个阶段执行postProcessBeanDefinitionRegistry方法。

好记性不如烂笔头 1614

从MapperScannerConfigurer看MyBatis自动扫描Mapper的机制

从MapperScannerConfigurer看MyBatis自动扫描Mapper的机制

懒人的博客 1万+
上一篇: Java垃圾回收机制
下一篇: Mybatis3源码分析(21)-Mapper实现-动态代理
风云叶易
博客等级 码龄16年 54粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值