主配置类@Configuration、组件扫描@ComponentScan

2023-12-31 14:08

本文主要是介绍主配置类@Configuration、组件扫描@ComponentScan,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 主配置
    • xml文件配置的方式
    • 注解的方式:主配置类@Configuration
    • @Configuration源码
  • 组件扫描:@ComponentScan
    • XML配置文件方式
    • @ComponentScan注解方式
    • @ComponentScan源码:
    • includeFilters指定规则扫描组件
    • 过滤规则
    • 自定义匹配规则FilterType.CUSTOM
  • 总结
    • 注解用法
    • 获取IoC容器的方法:

主配置

xml文件配置的方式

先按照我们以前配置的方式来使用Spring,给出主配置XML:
首先有一个Person类:

public class Person {private String name;private Integer age;public Person() {}public Person(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

主配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="person" class="com.ldc.bean.Person"><property name="age" value="18"></property><property name="name" value="张三"></property></bean>
</beans>

测试

public class MainTest {public static void main(String[]args){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");Person person = (Person) applicationContext.getBean("person");System.out.println(person);}
}

输出结果为:

Person{name=‘张三’, age=18}

注解的方式:主配置类@Configuration

首先我们先写一个配置类:其作用与xml配置文件相同,均是给Spring做出一些配置和导入一些组件

/***  配置类就等同以前的配置文件*/
@Configuration //告诉Spring这是一个配置类
public class MainConfig {//相当于xml配置文件中的<bean>标签,告诉容器注册一个bean//之前xml文件中<bean>标签有bean的class类型,那么现在注解方式的类型当然也就是返回值的类型//之前xml文件中<bean>标签有bean的id,现在注解的方式默认用的是方法名来作为bean的id@Beanpublic Person person() {return new Person("lisi",20);}}

测试:

public class MainTest {public static void main(String[]args){/*** 这里是new了一个AnnotationConfigApplicationContext对象,以前new的ClassPathXmlApplicationContext对象* 的构造函数里面传的是配置文件的位置,而现在AnnotationConfigApplicationContext对象的构造函数里面传的是* 配置类的类型*/ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);Person person = applicationContext.getBean(Person.class);System.out.println(person);}
}

输出结果为:

Person{name=‘张三’, age=18}

@Configuration源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {/*** Explicitly specify the name of the Spring bean definition associated* with this Configuration class. If left unspecified (the common case),* a bean name will be automatically generated.* <p>The custom name applies only if the Configuration class is picked up via* component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.* If the Configuration class is registered as a traditional XML bean definition,* the name/id of the bean element will take precedence.* @return the specified bean name, if any* @see org.springframework.beans.factory.support.DefaultBeanNameGenerator*/String value() default "";}

从@Configuration 这个注解点进去就可以发现这个注解上也标注了 @Component 的这个注解,说明被他标注的主配置类也纳入到IOC容器中作为一个组件

组件扫描:@ComponentScan

作用:自动扫描注册组件并可以指定特定的扫描规则

XML配置文件方式

在xml文件配置的方式,我们可以这样来进行配置:

    <!-- 包扫描、只要标注了@Controller@Service@Repository@Component 均可以将其作为组件扫描进来--><context:component-scan base-package="com.ldc"/>

@ComponentScan注解方式

以前是在xml配置文件里面写包扫描,现在我们可以在配置类里面写包扫描:

/*** 配置类就等同以前的配置文件*/
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.ldc")//相当于是xml配置文件里面的<context:component-scan base-package="com.ldc"/>
public class MainConfig {//相当于xml配置文件中的<bean>标签,告诉容器注册一个bean//之前xml文件中<bean>标签有bean的class类型,那么现在注解方式的类型当然也就是返回值的类型//之前xml文件中<bean>标签有bean的id,现在注解的方式默认用的是方法名来作为bean的id@Bean(value = "person")//通过这个value属性可以指定bean在IOC容器的idpublic Person person01() {return new Person("lisi",20);}}

测试:
我们创建BookController、BookService、BookDao这几个类,分别添加了@Controller、@Service、@Repository注解:

@Controller
public class BookController {
}
@Service
public class BookService {
}
    @Testpublic void test01() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}

结果如下:除开IOC容器自己要装配的一些组件外,还有是我们自己装配的组件

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDao
bookService
person

从上面的测试结果我们可以发现主配置类 MainConfig 也是IOC容器里面的组件,也被纳入了IOC容器的管理。

@ComponentScan源码:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;String resourcePattern() default "**/*.class";boolean useDefaultFilters() default true;ComponentScan.Filter[] includeFilters() default {};//这个是要排除的规则:是按注解来进行排除还是按照类来进行排除还是按照正则表达式来来进行排除ComponentScan.Filter[] excludeFilters() default {};boolean lazyInit() default false;@Retention(RetentionPolicy.RUNTIME)@Target({})public @interface Filter {FilterType type() default FilterType.ANNOTATION;@AliasFor("classes")Class<?>[] value() default {};@AliasFor("value")Class<?>[] classes() default {};String[] pattern() default {};}
}

这个时候,我们就可以这样来配置:

@Configuration
@ComponentScan(value = "com.ldc",excludeFilters = {//这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行排除//classes = {Controller.class,Service.class}表示的是标有这些注解的类给排除掉@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
})
public class MainConfig {@Bean(value = "person")public Person person01() {return new Person("lisi",20);}}

includeFilters指定规则扫描组件

我们也可以来配置includeFilters:指定在扫描的时候,只需要包含哪些组件
在用xml文件配置的方式来进行配置的时候,还要禁用掉默认的配置规则,只包含哪些组件的配置才能生效

<context:component-scan base-package=“com.ldc” use-default-filters=false/>

在这里插入图片描述
书写案例:

@Configuration
//excludeFilters = Filter[];指定在扫描的时候按照什么规则来排除脑哪些组件
//includeFilters = Filter[];指定在扫描的时候,只需要包含哪些组件
@ComponentScan(value = "com.ldc",includeFilters = {//这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行排除//classes = {Controller.class}表示的是标有这些注解的类给纳入到IOC容器中@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
},useDefaultFilters = false)
public class MainConfig {@Bean(value = "person")public Person person01() {return new Person("lisi",20);}}

过滤规则

public enum FilterType {ANNOTATION,ASSIGNABLE_TYPE,ASPECTJ,REGEX,CUSTOM;private FilterType() {}
}

书写案例

@Configuration
//excludeFilters = Filter[];指定在扫描的时候按照什么规则来排除脑哪些组件
//includeFilters = Filter[];指定在扫描的时候,只需要包含哪些组件
@ComponentScans(value = {@ComponentScan(value = "com.ldc",includeFilters = {//这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行匹配//classes = {Controller.class}表示的是标有这些注解的类给纳入到IOC容器中// FilterType.ANNOTATION 按照注解来进行匹配// FilterType.ASSIGNABLE_TYPE 按照给定的类型来进行匹配@Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),//按照给定的类型来进行匹配@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class})},useDefaultFilters = false)
})public class MainConfig {@Bean(value = "person")public Person person01() {return new Person("lisi",20);}}

下面的这两种是我们最常用的匹配规则:

FilterType.ANNOTATION 按照注解来进行匹配FilterType.ASSIGNABLE_TYPE
按照给定的类型来进行匹配

自定义匹配规则FilterType.CUSTOM

我们可以自己来写一个匹配规则的类:MyTypeFilter,这个类要实现TypeFilter这个接口

public class MyTypeFilter implements TypeFilter {/**** @param metadataReader  the metadata reader for the target class 读取到当前正在扫描的类的信息* @param metadataReaderFactory a factory for obtaining metadata readers 可以获取到其他任何类的信息* @return* @throws IOException*/@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//获取到当前类注解的信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//获取当前类的资源的信息(比如类的路径)Resource resource = metadataReader.getResource();//获取到当前正在扫描的类的信息ClassMetadata classMetadata = metadataReader.getClassMetadata();String className = classMetadata.getClassName();System.out.println("通过自定义的匹配规则--->"+className);return false;}
}

这个时候,我们就可以这样来用了:使用FilterType.CUSTOM

@Configuration
//excludeFilters = Filter[];指定在扫描的时候按照什么规则来排除脑哪些组件
//includeFilters = Filter[];指定在扫描的时候,只需要包含哪些组件
@ComponentScans(value = {@ComponentScan(value = "com.ldc",includeFilters = {//自定义匹配的规则@Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})},useDefaultFilters = false)
})public class MainConfig {@Bean(value = "person")public Person person01() {return new Person("lisi",20);}}

总结

注解用法

//配置类==配置文件
@Configuration //告诉Spring这是一个配置类@ComponentScans(
value = {
@ComponentScan(value="com.atguigu",includeFilters = {
/* @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
},useDefaultFilters = false)
}
)
//@ComponentScan value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
public class MainConfig {//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("person")
public Person person01(){
return new Person("lisi", 20);
}}

获取IoC容器的方法:

//获取xml配置文件时的IOC容器
//     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//    Person bean = (Person) applicationContext.getBean("person");
//    System.out.println(bean);
获注解配置时的IOC容器ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);Person bean = applicationContext.getBean(Person.class);System.out.println(bean);

这篇关于主配置类@Configuration、组件扫描@ComponentScan的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/556258

相关文章

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Spring Boot集成Logback终极指南之从基础到高级配置实战指南

《SpringBoot集成Logback终极指南之从基础到高级配置实战指南》Logback是一个可靠、通用且快速的Java日志框架,作为Log4j的继承者,由Log4j创始人设计,:本文主要介绍... 目录一、Logback简介与Spring Boot集成基础1.1 Logback是什么?1.2 Sprin

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

Gradle在国内配置镜像加速的实现步骤

《Gradle在国内配置镜像加速的实现步骤》在国内使用Gradle构建项目时,最大的痛点就是依赖下载贼慢,甚至卡死,下面教你如何配置国内镜像加速Gradle下载依赖,主要是通过改写repositori... 目录引言一、修改 build.gradle 或 settings.gradle 的 reposito

使用easy connect之后,maven无法使用,原来需要配置-Djava.net.preferIPv4Stack=true问题

《使用easyconnect之后,maven无法使用,原来需要配置-Djava.net.preferIPv4Stack=true问题》:本文主要介绍使用easyconnect之后,maven无法... 目录使用easGWowCy connect之后,maven无法使用,原来需要配置-DJava.net.pr

史上最全nginx详细参数配置

《史上最全nginx详细参数配置》Nginx是一个轻量级高性能的HTTP和反向代理服务器,同时也是一个通用代理服务器(TCP/UDP/IMAP/POP3/SMTP),最初由俄罗斯人IgorSyso... 目录基本命令默认配置搭建站点根据文件类型设置过期时间禁止文件缓存防盗链静态文件压缩指定定错误页面跨域问题

nginx负载均衡及详细配置方法

《nginx负载均衡及详细配置方法》Nginx作为一种高效的Web服务器和反向代理服务器,广泛应用于网站的负载均衡中,:本文主要介绍nginx负载均衡及详细配置,需要的朋友可以参考下... 目录一、 nginx负载均衡策略1.1 基本负载均衡策略1.2 第三方策略1.3 策略对比二、 nginx配置2.1

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮