• Spring注解驱动开发01(组件扫描使用详解)


    使用Spring注解代替XML的方式

    以前都是通过xml配bean的方式来完成bean对象放入ioc容器,即使通过@Aotuwire自动装配bean,还是要创建一个xml文件,进行包扫描,显得过于繁琐

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--    包扫描   属性:use-default-filters="false" 禁用全扫描-->
        <context:component-scan base-package="com.atguigu">
            <!--        排除标注了service注解的类扫描-->
            <!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
            <!--        只扫描service注解的类,默认全扫描,需要先禁用默认规则才能使用-->
            <!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
        </context:component-scan>
        
        <bean id="r1" class="com.atguigu.aop.service.BookService"/>
    </beans>
    

    使用注解的方式将bean组件加入到ioc容器

    1. 创建一个配置类
    //此注解告诉了spring这是一个配置类
    @Configuration
    //扫描com.xxx下的组件,将其加入到ioc容器
    @ComponentScan(value = "com.xxx")
    public class MainConfig {
        //将@Bean标注的组件加入到ioc容器,默认为方法名作为id,返回值作为bean类型
        @Bean
        public Person person(){
            return new Person();
        }
    }
    
    1. 测试ioc中已有的组件
    //AnnotationConfigApplicationContext 加载注解配置,获取ioc容器
            try (ConfigurableApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class)) {
                Person bean = ioc.getBean(Person.class);
                PersonController controller = ioc.getBean(PersonController.class);
                PersonServic servic = ioc.getBean(PersonServic.class);
                PersonDao dao = ioc.getBean(PersonDao.class);
                
                System.out.println(bean);
                System.out.println(controller);
                System.out.println(dao);
                System.out.println(servic);
    
            }
    

    打印结果

    com.atguigu.pojo.Person@1ddf84b8
    com.atguigu.controller.PersonController@1139b2f3
    com.atguigu.dao.PersonDao@7a69b07
    com.atguigu.service.PersonServic@5e82df6a
    

    注解@ComponentScan的使用

    修饰位置

    @Target({ElementType.TYPE}) 只能修饰在类上
    
    1. value属性
    //扫描com.xxx下的组件,将其加入到ioc容器
    @ComponentScan(value = "com.xxx")
    
    1. 排除和包含
      可通过相关属性来排除不需要加入到ioc容器的组件,或者指定ioc中只包含该组件
    • 排除excludeFilters
    //看源码,类型为ComponentScan.Filter[]
    ComponentScan.Filter[] excludeFilters() default {};
    
    //所以传入该类型参数
    @ComponentScan(value = "com.atguigu",excludeFilters = {
            //不扫描@controller和service注解,type默认为注解类型,可以不写
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})})
    

    @ComponentScan.Filter中的type的形式

    1. 通过注解
          type = FilterType.ANNOTATION,
          classes = {Controller.class, Service.class}
          表示通过注解类型来筛选需要排除的类,classes是一个数组,可以申明多个
          表示被@Cotroller或者被@Service修饰的类都不加入到ioc容器
    
    1. 通过类型
          type = ASSIGNABLE_TYPE,
          classes = {PersonController.class, PersonService.class}
          表示通过类的类型来筛选需要排除的类,classes是一个数组,可以申明多个
          表示为PersonCotroller类型的组件或者被PersonService类型的组件都不加入到ioc容器
    
    1. 正则类型
          type = FilterType.REGEX
    
    1. 自定义过滤类型,需要写一个TypeFilter的实现类
      创建实现类
        /**
         * @param metadataReader 当前正在扫描的类的信息
         * @param metadataReaderFactory 可以获取到其它任何类信息
         * @return 是否执行过滤
         */
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            //获取当前类注解的信息
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //获取当前正在扫描的类的定义信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //获取当前类的资源信息(类的路径)
            Resource resource = metadataReader.getResource();
    
            String className = classMetadata.getClassName();
            System.out.println(className);
            if (className.contains("Dao")){ //如果类名包含了Dao,则执行过滤
                return true;
            }
            return false;
        }
    

    使用

          //指定type
          type = FilterType.CUSTOM,
          classes = {Myfilter.class} //自己写的类信息
    

    打印结果

    加上dao
                Person bean = ioc.getBean(Person.class);
                PersonController controller = ioc.getBean(PersonController.class);
                PersonServic servic = ioc.getBean(PersonServic.class);
                PersonDao dao = ioc.getBean(PersonDao.class);
    
                System.out.println(bean);
                System.out.println(controller);
                System.out.println(dao);
                System.out.println(servic);
    
    抱错,找不到dao,因为已经被过滤了
    No qualifying bean of type 'com.atguigu.dao.PersonDao' available
    

    注释掉dao

    // 打印结果没问题
    com.atguigu.pojo.Person@7a69b07
    com.atguigu.controller.PersonController@5e82df6a
    com.atguigu.service.PersonServic@3f197a46
    
    • 包含includeFilters,用法类似,我就不多说了
    课堂无作为,Code写春秋
  • 相关阅读:
    IBM openblockchain学习(五)--consensus源码分析
    Linux内核抢占机制
    IBM openblockchain学习(四)--crypto源码分析
    IBM openblockchain学习(三)--Ledger源码分析
    IBM openblockchain学习(二)--chaincode源码分析
    瞎谈“认知计算”
    IBM openblockchain学习(一)--obc-peer环境搭建
    10G数据不用框架快速去重
    Spark学习笔记(一)--Spark架构
    HDU2255 【模板】KM算法
  • 原文地址:https://www.cnblogs.com/hea2t/p/13528762.html
Copyright © 2020-2023  润新知