Spring排除功能

我们都知道component-scan在springmvc或者springboot中可以扫描包路径,但是我们如何使用里面的属性排除不需要扫描的类?

方式一:

使用spring的xml配置方式实现,这个是基本功,知道这种方式,那么注解方式就容易理解了

<!-- 定义项目扫描包的路径,并且排除ApplicationContextConfig和WebSpringMVCServletConfig-->

<context:component-scan base-package="com.leo"> 
<context:exclude-filter type="assignable" expression="com.leo.config.ApplicationContextConfig"/> 
<context:exclude-filter type="assignable" expression="com.leo.config.WebSpringMVCServletConfig"/>
</context:component-scan>

里面的type有以下几种类型,用法不一一举例了,大家可以自己尝试。

过滤器类型描述
annotation过滤器扫描使用注解标注的那些类,并通过expression指定注解全类名
assignable过滤器扫描派生于expression属性指定的类
aspectj过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
custom使用自定义的org.springframework.core.type.TypeFliter实现类,并通过expression指定全类名
regex过滤器扫描类的名称与expression属性指定正则表达式所匹配的那些类

方式二:

 这种是通过@component-scan方式在配置扫描包路径的时候直接不包含要排除的包。举例说明一下如下:
项目的包路径是:com.leo.configcon.leo.controllercon.leo.service
我不需要扫描com.leo.config,那么配置@component-scan的时候就可以使用下面的配置直接不用扫描com.leo.config

@ComponentScan(basePackages = {"con.leo.controller","con.leo.service"})

方式三:

其实大部分的情况是我们只有com.leo.config下面的某个类需要排除,那么可以使用FilterType.ASSIGNABLE_TYPE排除。参考如下配置

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ApplicationContextConfig.class, WebSpringMVCServletConfig.class}))

方式四:

如果上面的class非常多的话,使用上面的方式就不太合适了,那我们可以使用FilterType.ANNOTATION加自定义注解去实现。参考如下配置

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ScanIgnore.class))

自定义@ScanIgnore实现

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ScanIgnore {}

方式五:

也可通过自定义的过滤器去实现。使用FilterType.CUSTOM加上自定义的过滤器

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class))

自定义过滤器MyTypeFilter

public class MyTypeFilter implements TypeFilter{ 
/** 
 * 过滤当前类的信息,如果包含的则不需要扫描 * 
 * @param metadataReader 读取当前正在扫描的信息 
 * @param metadataReaderFactory 可以获取到其他任何类的信息 
 * @return 
 * @throws IOException 
 */ 
@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(); 

//包含这个包路径的则被拦截 
if(className.startsWith("com.leo.config"))
{ 
System.out.println("===============>"+className); 
return false; 
} 
return true; 
}
}

方式六

通过表达式来实现排除,使用FilterType.REGEX,配合pattern来实现。参考配合如下:

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.leo.config.*"))

方式七

@SpringBootApplication(exclude={DataSourceAutoConfiguration.calss})这个里面exclude只能排除auto-configuration类型的类,也就是只能排除自动装配的类,普通通过@component,@controller,@service等注解定义的类是无法使用该方法排除的

方式八

如果是在类中使用@Bean声明的类实例,得不到类限定名称,也得不到该类的 class 。因此无法使用上述方法进行排除,可以使用下面的方法进行处理

解决方案1:

使用BeanDefinitionRegistryPostProcessor,直接在 解析完bean的注册信息后,直接移除就行,这样就不会创建bean(该方式是通用型最好的方式,适用于动态添加或者删除各种方式注册的bean

@Component
public class RemoveRegistyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    //移出bean。 userServiceImpl2是bean的名称
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        if (beanDefinitionRegistry.containsBeanDefinition("userServiceImpl2")){
            beanDefinitionRegistry.removeBeanDefinition("userServiceImpl2");
        }

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

解决方案2:

在使用@Bean注解自动装配类实例时,使用@Conditional进行判断,如果符合某种条件,则装配该实例。

总结:

以上都是通过excludeFilters实现排除不需要类的方式,如果是反向操作,需要添加需要的类,则将上面的关键字替换为includeFilters就好了。如果是配置文件的实现则

<context:exclude-filter></context:exclude-filter>替换成<context:include-filter></context:include-filter>spring的配置文件是基础,后面的无论是springmvc亦或者是springboot都是在这个基础上扩展的。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值