spring如何排除bean的注入

前言

在做项目或写单元测试时,需要对某个特定的bean进行排除,为了方便大家的使用,这里对几种常见的方案进行总结。

常见方法

  1. 排除指定注解的类-annotation
  2. 排查指定切面的类-aspectj
  3. 排除继承至某接口或类的类-assignable
  4. 排除符合指定匹配规则的类-regex
  5. 叠加进行排除
  6. 排除符合自定义规则的类-custom
  7. 通过BeanDefinitionRegistryPostProcessor进行排除

注源码解释:
    "annotation" indicates an annotation to be present or meta-present at the type level in target components;
    "assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
    "aspectj" indicates an AspectJ type pattern expression to be matched by the target components;
    "regex" indicates a regex pattern to be matched by the target components' class names;
    "custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.

代码示例

1、排除指定注解的类-annotation

通过xml配置,可以将配置了@Service注解的类都排除掉

    <context:component-scan base-package="com.coderp">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>
2、排查指定切面的类-aspectj

采用aspectj过滤,“com.coderp.service.impl…*”:表示下面的包及其子包(包切入点)

    <context:component-scan base-package="com.coderp" >
        <context:exclude-filter  type="aspectj" expression="com.coderp.service.impl..*"/>
    </context:component-scan>

采用aspectj过滤,"*…Log":com.coderp所有的包及其子包下,只要有Log类,就会被排除

        <context:component-scan base-package="com.coderp" >
            <context:exclude-filter  type="aspectj" expression="*..Log"/>
        </context:component-scan>
3、排除继承至某接口或类的类-assignable

通过xml配置,将Log类或继承Log的类都排除掉

    <context:component-scan base-package="com.coderp">
        <context:exclude-filter type="assignable" expression="com.coderp.service.impl.Log"/>
    </context:component-scan>
4、排除符合指定匹配规则的类-regex

通过xml配置,将符合正则表达式模式的类进行排除

    <context:component-scan base-package="com.coderp">
        <context:exclude-filter type="regex" expression="com.coderp.service.impl.PayServiceImpl"/>
    </context:component-scan>
5、叠加进行排除

通过xml配置,可以对多种过滤方式进行组合,如下组合assignable和aspectj方式

    <context:component-scan base-package="com.coderp">
        <context:exclude-filter type="assignable" expression="com.coderp.service.impl.Log"/>
        <context:exclude-filter type="aspectj" expression="com.coderp.aspect..*"/>
    </context:component-scan>
6、排除符合自定义规则的类-custom

自定义过滤规则MyTypeFilter,当返回true则将符合规则的类进行排除,如下的过滤规则会将类名称中包含“PayServiceImpl”的都会被排除。

public class MyTypeFilter implements TypeFilter {
    /**
     * 当我们实现TypeFilter接口时,需要实现TypeFilter接口中的match()方法,
     * match()方法的返回值为boolean类型。当返回true时,表示符合规则,
     * 会排除在Spring容器中;当返回false时,表示不符合规则,会包含在Spring容器中。
     * @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();
        // 获取当前类的资源信息。例如类的路径等信息
        try {
            Resource resource = metadataReader.getResource();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String className = classMetadata.getClassName();
        System.out.println("当前正在扫描的类----->"+className);

        System.out.println(className.contains("PayServiceImpl"));
        return className.contains("PayServiceImpl");
    }
}
    <context:component-scan base-package="com.coderp" >
        <context:exclude-filter type="custom" expression="com.coderp.filter.MyTypeFilter"/>
    </context:component-scan>
7、通过BeanDefinitionRegistryPostProcessor进行排除

以上方式都是通过xml配置进行过滤的,当然也可以通过注解进行过滤,那能不能用直接用代码进行过滤呢?显然是可以的,这里利用BeanDefinitionRegistryPostProcessor类进行处理。如下示例,将“payServiceImpl”排除

@Service
public class RemoveRegistyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        if (beanDefinitionRegistry.containsBeanDefinition("payServiceImpl")){
            beanDefinitionRegistry.removeBeanDefinition("payServiceImpl");
        }
    }

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

    }
}

总结

通过上面的方法介绍和代码示例,希望能够帮助到大家,关键还是大家多练习,在工作中及时总结。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值