使用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,用法类似,我就不多说了

Spring注解驱动开发01(组件扫描使用详解)的更多相关文章

  1. 【Spring注解驱动开发】组件注册-@ComponentScan-自动扫描组件&指定扫描规则

    写在前面 在实际项目中,我们更多的是使用Spring的包扫描功能对项目中的包进行扫描,凡是在指定的包或子包中的类上标注了@Repository.@Service.@Controller.@Compon ...

  2. Spring注解驱动开发(一)-----组件注册

    注册bean xml方式 1.beans.xml-----很简单,里面注册了一个person bean <?xml version="1.0" encoding=" ...

  3. 0、Spring 注解驱动开发

    0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...

  4. 【Spring注解驱动开发】使用@Import注解给容器中快速导入一个组件

    写在前面 我们可以将一些bean组件交由Spring管理,并且Spring支持单实例bean和多实例bean.我们自己写的类,可以通过包扫描+标注注解(@Controller.@Servcie.@Re ...

  5. 【spring 注解驱动开发】spring组件注册

    尚学堂spring 注解驱动开发学习笔记之 - 组件注册 组件注册 1.@Configuration&@Bean给容器中注册组件 2.@ComponentScan-自动扫描组件&指定扫 ...

  6. 【Spring注解驱动开发】使用@Scope注解设置组件的作用域

    写在前面 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象.如果每次 ...

  7. 【Spring注解驱动开发】自定义TypeFilter指定@ComponentScan注解的过滤规则

    写在前面 Spring的强大之处不仅仅是提供了IOC容器,能够通过过滤规则指定排除和只包含哪些组件,它还能够通过自定义TypeFilter来指定过滤规则.如果Spring内置的过滤规则不能够满足我们的 ...

  8. 【Spring注解驱动开发】如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!

    在 冰河技术 微信公众号前面的文章中,我们介绍了如何使用注解来自动装配Spring组件.之前将的都是在来的字段上添加注解,那有没有什么方法可以实现方法.构造器位置的自动装配吗?今天我们就一起来探讨下如 ...

  9. 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!

    写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...

随机推荐

  1. ngx lua获取时间戳的几种方式

    原创自由de单车 最后发布于2017-02-14 14:58:43 阅读数 18218 收藏 在ngx_lua里,获取时间相关信息的方式大概有4种(见下面代码): print(string.forma ...

  2. Android中Activity的启动模式和使用场景

    一.为什么需要启动模式 在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些A ...

  3. ImportError: /lib64/libm.so.6: version `CXXAB_1.3.8.' not found (required by /usr/local/python37/lib/python3.7/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so)

    问题背景 使用在AI项目中,由于需要用到tensorflow,scipy,sklearn等这些库,所以需要libstdc++库. 问题原因 这个问题的出现与写的代码无关,只与操作系统的libstdc+ ...

  4. 详解Java的对象创建

    1. 前言 在<还不清楚怎样面向对象?>和<面向对象再探究>两篇文章中,都介绍了关于面向对象程序设计的概念和特点.其中也涉及到了许多代码,比如: Dog dog = new D ...

  5. plantuml 基本语法(转摘)

    <div id="topics"> <div class="post"> <h1 class="postTitle&qu ...

  6. 什么是PHP 面向对象

    PHP 面向对象 在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象. 在现实 ...

  7. PHP is_writable() 函数

    定义和用法 is_writable() 函数检查指定的文件是否可写. 如果文件可写,该函数返回 TRUE. 语法 is_writable(file) 参数 描述 file 必需.规定要检查的文件. 提 ...

  8. Skill 脚本演示 ycChangeViaNumber.il

    https://www.cnblogs.com/yeungchie/ ycChangeViaNumber.il 使用鼠标滚轮快速修改 Via 的数量. 回到目录

  9. 牛客练习赛64 红色的樱花 exgcd 贪心

    LINK:The red sakura 暴怒狂樱 血染京都. 这题质量不咋地 这题也没啥营养. 不过还是存在值得学习的地方的. 一个trick n行 m列 第一行与第n行相连 第1列和第m列相连的时候 ...

  10. Vue通过Blob对象实现导出Excel功能

    不同的项目有不同的导出需求,有些只导出当前所显示结果页面的表格进入excel,这个时候就有很多插件,比如vue-json-excel或者是Blob.js+Export2Excel.js来实现导出Exc ...