主配置类@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+MyBatis-Flex配置ProxySQL的实现步骤

《SpringBoot+MyBatis-Flex配置ProxySQL的实现步骤》本文主要介绍了SpringBoot+MyBatis-Flex配置ProxySQL的实现步骤,文中通过示例代码介绍的非常详... 目录 目标 步骤 1:确保 ProxySQL 和 mysql 主从同步已正确配置ProxySQL 的

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

解决Spring运行时报错:Consider defining a bean of type ‘xxx.xxx.xxx.Xxx‘ in your configuration

《解决Spring运行时报错:Considerdefiningabeanoftype‘xxx.xxx.xxx.Xxx‘inyourconfiguration》该文章主要讲述了在使用S... 目录问题分析解决方案总结问题Description:Parameter 0 of constructor in x

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@