metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { String return isConditionMatch(metadataReader); } } return false; } 总结MapperScannerConfigurer的作用 的目录递归搜索接口,将它们注册为MapperFactoryBean SqlSessionFactoryBean 类注释 创建Mybatis的SqiSessionFactory,用于Spring上下文中进行共享 MapperFactoryBean是这一切的答案(MapperFactoryBean:注意看我的名字---Mapper的工厂!!) 注意这个工厂仅仅注入接口不注入实现类 类图找关键方法 [MapperFactoryBean] 看类图,又看到了InitializingBean和FactoryBean!!!
-- (2) session工厂 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean -- (2) session<em>工厂</em> --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean //3.9 return this.sqlSessionFactoryBuilder.build(configuration); } 如上代码(3.1)创建了一个Spring事务管理<em>工厂</em> (3.5)解析mapper.xml中/mapper/resultMap标签下内容,然后存放到Configuration对象的resultMaps缓存里面,这里需要提一下,所有的mapper.xml文件<em>共享</em>一个 代码(5.13)设置session<em>工厂</em>到bean定义。
一、Spring源码基础组件 阅读源码时候,接口与类过多,可以对照这里查看对应的关系 1、bean定义接口体系 2、bean工厂接口体系 3、ApplicationContext上下文体系 二、AnnotationConfigApplicationContext ); //关闭容器 context.close(); } } AnnotationConfigApplicationContext的构造方法: 1、创建bean工厂 beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // 3.6.注册事件监听工厂 EventListenerMethodProcessor 事件监听后置处理器 internalEventListenerFactory = DefaultEventListenerFactory 事件监听工厂 metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader
TypeFilter定义如下: public interface TypeFilter { /** * 指定类是否匹配组件扫描的过滤规则 * @param metadataReader 目标类的元数据reader * @param metadataReaderFactory 可以获取其他类元数据reader的工厂 * @return 是否匹配过滤规则 * @throws IOException */ boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory 该方法有两个参数: metadataReader:当前扫描到的目标类的元数据读取器,可以通过该对象获取目标类的信息; metadataReaderFactory:其他类的元数据工厂了,可以获取其他类的信息 metadataReader, MetadataReaderFactory metadataReaderFactory){ //获取目标类元信息 ClassMetadata
Bean的名称,如果通过工厂Bean创建 @Nullable private String factoryBeanName; // 工厂方法的名称,用于通过静态方法或工厂Bean public ScannedGenericBeanDefinition(MetadataReader metadataReader) { // 校验 metadataReader 不为 null Assert.notNull(metadataReader, "MetadataReader must not be null"); // 从 MetadataReader 获取注解元数据 this.metadata = metadataReader.getAnnotationMetadata(); // 设置 Bean 类的名称 setBeanClassName(this.metadata.getClassName ()); // 设置扫描到的资源 setResource(metadataReader.getResource()); } @Override // 返回 Bean 类的注解元数据 public
MetadataReaderFactory MetadataReader的实现都并未public暴露出来,所以我们若想得到它的实例,就只能通过此工厂。 IOException { return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader()); } } 此工厂生产的是 此类可认为从没有被Spring内部使用过,暂且可忽略(spring-data工程有用) Factory工厂的实现都是非常简单的,毕竟只是为了生产一个实例而已。 下面我也给出使用案例: 因为MetadataReader的实现类都是包级别的访问权限,所以它的实例只能来自工厂 public static void main(String[] args) throws metadataReader = readerFactory.getMetadataReader(MetaDemo.class.getName()); MetadataReader metadataReader
Component,构造BeanDefinition对象(实际为ScannedGenericBeanDefinition) 利用BeanDefinitionRegister注册BeanDefinition到bean工厂中 ,BeanDefinitionRegister是spring默认bean工厂DefaultListableBeanFactory的一个接口,用于注册BeanDefinition; 先祭出类继承图: resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //bean工厂 *meteDataFactory根据Resouce获取到MetadataReader对象 *MetadataReader */ MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader
com.jack.remote.service")); List<String> classNames = Arrays.stream(resources).map(resource -> { MetadataReader metadataReader = null; try { metadataReader = metadataReaderFactory.getMetadataReader resource); } catch (IOException e) { e.printStackTrace(); } return metadataReader.getClassMetadata }); } 三、装配 对于远程service包下的类,就可以直接使用@Autowired来装配 总结 至此FactoryBean已经完结,对于它的作用已经了解:它是一个能生产或修饰对象生成的工厂 Bean,类似于设计模式中的工厂模式和装饰器模式
TypeFilter 类型:接口 作用:自定义类型过滤器 范例: public class MyTypeFilter implements TypeFilter { public boolean match(MetadataReader mr, MetadataReaderFactory mrf) throws IOException { ClassMetadata cm = metadataReader.getClassMetadata ClassPathBeanDefinitionScanner(r, false); TypeFilter tf = new TypeFilter() { public boolean match(MetadataReader class SpringConfig { } 10.7.bean初始化过程解析 10.7.1.bean初始化过程解析 BeanFactoryPostProcessor 作用:定义了在bean工厂对象创建后 ,bean对象创建前执行的动作,用于对工厂进行创建后业务处理 运行时机:当前操作用于对工厂进行处理,仅运行一次 BeanPostProcessor 作用:定义了所有bean初始化前后进行的统一动作
Users/tenmao/Workspace/boot/tenmao-cond/target/classes/com/tenmao/cond/UserManager.class"); //元数据解析器工厂 CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(); //元数据解析器 MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); //解析出来的类元数据 ClassMetadata classMetadata = metadataReader.getClassMetadata(); System.out.println(classMetadata); } 注意:整个过程程序并没有使用
FilterType.CUSTOM的使用 定义一个TypeFilter的实现类MyTypeFilter public class MyTypeFilter implements TypeFilter { /** * metadataReader :读取到的当前正在扫描的类的信息 * metadataReaderFactory:可以获取到其他任何类信息的 */ public boolean match(MetadataReader metadataReader (); //获取当前正在扫描的类的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //获取当前类资源 (类的路径) Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName 6)FactoryBean(工厂Bean) 1)默认获取到的是工厂bean调用getObject创建的对象 2)要获取工厂Bean本身,我们需要给id前面加一个&colorFactoryBean 编写FactoryBean
classMetadata = metadataReader.getClassMetadata(); // 获取当前类资源(类的路径) Resource resource = metadataReader.getResource(); // 获取这个类名 String className = classMetadata.getClassName 返回需要导入的组件的全类名数组. 3) : ImportBeanDefinitionRegistrar : 手动注册Bean到容器中 4 : 使用Spring提供的FactoryBean(工厂 Bean) 1) : 默认获取到的是工厂bean调用getObject创建的对象 2) : 要获取工厂Bean本身,我们需要给id前面加一个& ColorFactoryBean getBean() { return new ColorFactoryBean(); } public void test() { //工厂
name-generator"; //模板引用 private static final String ATTRIBUTE_TEMPLATE_REF = "template-ref"; //工厂引用 private static final String ATTRIBUTE_FACTORY_REF = "factory-ref"; //映射工厂bean类 private static 相反,创建一个仅包含此映射器扫描器的BeanFactory并对工厂进行后处理。 reader,也即拿到扫描文件信息 MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource (MetadataReader metadataReader) throws IOException { //排查过滤器 for (TypeFilter tf : this.excludeFilters
BeanDefinitionReader的核心方法包括以下几个:BeanDefinitionRegistry,用来注册bean定义,相当于一个工厂BeanNameGenerator,用来生成bean名字的生成器 框架中的一个重要接口,他就是Spring用于管理Bean对象的创建和管理,看他的几个主要方法就知道了:getBean,可以根据name、type等获取bean对象containsBean,是否bean工厂中有某个对象 BeanFactoryPostProcessorBeanFactoryPostProcessor表示Bean工厂的后置处理器,其实和BeanPostProcessor类似,BeanPostProcessor MetadataReader、ClassMetadata、AnnotationMetadataSpring启动时需要扫描指定包路径下的所有类文件来获取需要注入或管理的Bean信息。 System.out.println(metadataReader.getClassMetadata().getClassName()); metadataReader.getAnnotationMetadata
com.summer.test.service"); System.out.println(applicationContext.getBean(UserService.class)); BeanFactory Bean工厂 BeanFactory 表示 Bean 工厂,负责创建 Bean,提供获取 Bean 的 API。 ApplicationContext 提供一下功能: 用于访问应用程序组件的Bean工厂方法。从 ListableBeanFactory 继承; 以通用方式加载文件资源的能力。 BeanFactoryPostProcessor Bean 工厂后置处理器 BeanFactoryPostProcessor 表示 Bean 工厂的后置处理器,其实和 BeanPostProcessor metadataReaderFactory = new SimpleMetadataReaderFactory(); // 构造 MetadataReader MetadataReader metadataReader
(metadataReader)) {//<5> ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader 这里不理解的不要心急,下面还会讲到ClassPathScanningCandidateComponentProvider的isCandidateComponent(MetadataReader metadataReader ) {//<3> if (tf.match(metadataReader, getMetadataReaderFactory())) { return isConditionMatch(metadataReader isCandidateComponent(MetadataReader metadataReader)在<2>和<3>会按照我们在@CommponScan设定的excludeFilters和includeFilters 之后将beanFactory传给<2>处和<3>处的方法,从方法注释可以看到,<2>处会调用bean工厂后置处理器,<3>处会用beanFactory来初始化剩余的非懒加载单例对象,即我们编写的dao、
(Class类型),包括工厂方法的返回类型,工厂方法的Method对象 构造函数、构造函数形参类型 Bean的class对象 可以看到,RootBeanDefinition与AbstractBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; ... // 它只有一个构造函数:必须传入MetadataReader public ScannedGenericBeanDefinition(MetadataReader metadataReader) { Assert.notNull(metadataReader , "MetadataReader must not be null"); this.metadata = metadataReader.getAnnotationMetadata(); setBeanClassName ,而所有的@Bean注解的方法会成为工厂方法,通过工厂方法实例化Bean,而不是直接通过构造函数初始化(所以我们方法体里面可以很方便的书写逻辑。。。)
builder.getBeanDefinition()); } .....忽略不必要代码..... } 这一段代码最终的逻辑简单来说就是构建了一个自定义扫描器MapperScannerConfigurer然后注册到Bean工厂中 InitializingBean, ApplicationContextAware, BeanNameAware { /** * 自定义扫描器 * @param registry 注册到bean工厂的工具类 , metadataReaderFactory) -> { String className = metadataReader.getClassMetadata().getClassName if (resource.isReadable()) { try { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
> markerInterface() default Class.class; 5.构造工厂 Class<? metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { return metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { String metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { String String userName) { this.userName = userName; } } (1)通过实现BeanFactoryPostProcessor(Bean工厂的后置处理器
().equals(metadataReader.getClassMetadata().getClassName()); } } @Component public class User { (metadataReader) && isAutoConfiguration(metadataReader); } } 4、@Conditional注解 我们说SpringBoot约定大于配置 metadataReaderFactory) { String className = beanDef.getBeanClassName(); // 获取下类名,如果类名为空或者该类为工厂类 metadataReader = metadataReaderFactory.getMetadataReader(className); // 读取类的元数据信息,这里面包括注解等信息 metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if