网站系统报价方案模板下载,西安网站开发建设,官方网站建设 就问磐石网络专业,珠海市建设工程交易网Spring深入理解之ComponentScan
一、概述
ComponentScan顾名思义包扫描#xff0c;底层其实就可以通过递归算法反射将其装载成bean来实现的#xff0c;实在开发过程中#xff0c;Spring已经帮我们实现好了#xff0c;我们其实就可以直接使用XML或者注解的形式来进行业务处…Spring深入理解之ComponentScan
一、概述
ComponentScan顾名思义包扫描底层其实就可以通过递归算法反射将其装载成bean来实现的实在开发过程中Spring已经帮我们实现好了我们其实就可以直接使用XML或者注解的形式来进行业务处理。
二、ComponentScan的作用
ComponentScan注解有两个作用
作用一扫描含有ComponentControllerService和Repository的类并将其注入到spring容器中。
作用二扫描含有Configuration的类并使其生效。
分析作用一相信大家都明白其含义再次不在赘述。作用二举例说明例如Config2可以扫描到config2_test目录该目录下不仅含有ComponentControllerService和Repository注解标注的四个类还包含Config1配置类。Config1配置类可以扫描到config1_test目录并且里面还包含一个Bean注解。
三、同一个配置类上多个ComponentScan可能会报错
下面的配置类在我公司电脑的idea版本里是可以将config3_test目录下的所有类都注册到spring容器中但是在我家里的电脑上以及另一个同事的电脑上会报编译期错误代码运行也会出错。
四、ComponentScans的使用
由于同一个类上直接写多个ComponentScan可能会报错因此建议使用ComponentScans它可以解决直接在一个配置类上写多个ComponentScan在有些电脑或idea版本上报错的问题。 ComponentScan 详解
ComponentScan 的作用就是根据定义的扫描路径把符合扫描规则的类装配到spring容器中注解定义如下。
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 {};}
}basePackages与value: 用于指定包的路径进行扫描
basePackageClasses: 用于指定某个类的包的路径进行扫描
nameGenerator: bean的名称的生成器
useDefaultFilters: 是否开启对ComponentRepositoryServiceController的类进行检测
includeFilters: 包含的过滤条件
FilterType.ANNOTATION按照注解过滤FilterType.ASSIGNABLE_TYPE按照给定的类型FilterType.ASPECTJ使用ASPECTJ表达式FilterType.REGEX正则FilterType.CUSTOM自定义规则
excludeFilters: 排除的过滤条件用法和includeFilters一样
我的工程结构如下测试对controller和service的扫描其中HelloController没有加Controller等任何注解就是一个普通类。
修改配置类如下应用默认的过滤器扫描service包
Configuration
ComponentScan(value com.xhx.spring.service,useDefaultFilters true
)
public class MyConfig {
}系统注入了两个service进去
改成如下所示HelloController所在的包的类也被扫描了进去
Configuration
ComponentScan(value com.xhx.spring.service,useDefaultFilters true,basePackageClasses HelloController.class
)
public class MyConfig {
}系统中会注入下面就给类 把默认的过滤器关掉扫描带Controller注解的。
Configuration
ComponentScan(value com.xhx.spring,useDefaultFilters false,includeFilters {ComponentScan.Filter(type FilterType.ANNOTATION,classes {Controller.class})}
)
public class MyConfig {
}按照类的类型扫描虽然HelloController没有加注解但是被注入到了spring容器中
Configuration
ComponentScan(value com.xhx.spring,useDefaultFilters false,includeFilters {ComponentScan.Filter(type FilterType.ASSIGNABLE_TYPE,classes {HelloController.class})}
)
public class MyConfig {
}自定义扫描过滤器
package com.xhx.spring.componentscan.config;import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;import java.io.IOException;public class MyTypeFilter implements TypeFilter {Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {String className metadataReader.getClassMetadata().getClassName();if(className.contains(Controller)){return true;}return false;}
}修改配置类
Configuration
ComponentScan(value com.xhx.spring,useDefaultFilters false,includeFilters {ComponentScan.Filter(type FilterType.CUSTOM,classes {MyTypeFilter.class})}
)
public class MyConfig {
}输出结果
输出spring容器中的bean的测试类只过滤输出了名字中含有hello的类。
package com.xhx.spring.componentscan;import com.xhx.spring.componentscan.config.MyConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;RunWith(SpringRunner.class)
SpringBootTest
public class ComponentScanApplicationTests {Testpublic void testLoads() {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(MyConfig.class);ListString hello Arrays.stream(context.getBeanDefinitionNames()).collect(Collectors.toList());hello.stream().filter(name-name.contains(hello)).peek(System.out::println).count();}}