注解扫描
在 Spring 框架中,注解扫描(Annotation Scanning)是一种自动发现和注册带有特定注解的组件的机制。通过注解扫描,Spring 可以自动将带有特定注解的类注册为 Bean,并将其纳入到应用程序上下文中进行管理。
要配置注解扫描,可以使用 @ComponentScan
注解或通过 XML 配置文件进行配置。
XML 方式
我们需要再 Spring 的配置文件中引入 context 命名空间,然后使用 标签进行扫描的配置。
<?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"> <!-- 配置扫描包 --> <context:component-scan base-package="world.xuewei, world.zhangsan" use-default-filters="true"> </context:component-scan> </beans>
我们需要指定
base-package
属性,配置需要扫描的包路径(多个包用 ,
分割),这样默认扫描策略就会扫描对应包及其子包下的 Bean。use-default-filters
属性表示是否开启默认扫描策略,默认为 true 表示开启。
排除方式
我们可以在 内通过
标签配置排除策略,配置排除策略需要我们开启默认的扫描策略,即
use-default-filters="true"
。
可以通过为标签的 type 属性指定策略,expression 属性指定对应策略的表达式内容。Spring 提供了五种策略可以使用:
- assignable:指定某一类型加入策略。expression 需要指定为某个类的全限定类名。
- annotation:指定某一注解加入策略,标记此注解的类都进行策略决策。expression 需要指定为某个注解类的全限定类名。
- aspectj:指定切入点表达式加入策略(只包含包名和类名部分),expression 值为切入点表达式。
- regex:指定正则表达式加入策略,expression 值为正则表达式。
- custom:指定自定义过滤器加入策略,expression 值过滤器类的 Class。
<?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"> <!-- 配置扫描包 --> <context:component-scan base-package="world.xuewei, world.zhangsan" use-default-filters="true"> <context:exclude-filter type="assignable" expression="world.xuewei.entity.Account"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:exclude-filter type="aspectj" expression="world.xuewei.service..*"/> <context:exclude-filter type="regex" expression=".*Test"/> <context:exclude-filter type="custom" expression="world.xuewei.filter.MyCustomFilter"/> </context:component-scan> </beans>
包含方式
我们可以在 内通过
标签配置包含策略,配置包含策略需要我们关闭默认的扫描策略,即
use-default-filters="false"
。
可以通过为标签的 type 属性指定策略,expression 属性指定对应策略的表达式内容。Spring 提供了五种策略可以使用:
- assignable:指定某一类型加入策略。expression 需要指定为某个类的全限定类名。
- annotation:指定某一注解加入策略,标记此注解的类都进行策略决策。expression 需要指定为某个注解类的全限定类名。
- aspectj:指定切入点表达式加入策略(只包含包名和类名部分),expression 值为切入点表达式。
- regex:指定正则表达式加入策略,expression 值为正则表达式。
- custom:指定自定义过滤器加入策略,expression 值过滤器类的 Class。
<?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"> <!-- 配置扫描包 --> <context:component-scan base-package="world.xuewei, world.zhangsan" use-default-filters="false"> <context:include-filter type="assignable" expression="world.xuewei.entity.Account"/> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:include-filter type="aspectj" expression="world.xuewei.service..*"/> <context:include-filter type="regex" expression=".*Test"/> <context:include-filter type="custom" expression="world.xuewei.filter.MyCustomFilter"/> </context:component-scan> </beans>
包含方式与排除方式需要互斥使用
注解方式
@ComponentScan
注解是 Spring 提供的一种基于注解的配置方式,它可以在 Java 类上直接使用,也可以在配置类上使用。
@ComponentScan
注解包含几个重要的属性:basePackages
、 excludeFilters
、 includeFilters
、 useDefaultFilters
。作用和上述 XML 方式一样。
@ComponentScan(basePackages = "world.xuewei", excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Account.class), @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class), @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test"), @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "world.xuewei.dao..*"), @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyCustomFilter.class), }) @Component public class AnnotationTest { // ... }