Java 查找实现特定接口但不包括Spring框架扩展接口子实现的单个类

Java 查找实现特定接口但不包括Spring框架扩展接口子实现的单个类,java,spring,spring-boot,java-8,Java,Spring,Spring Boot,Java 8,我需要在我的spring boot应用程序中找到只实现一个特定接口的类。 我面临的问题是ClassPathBeanDefinitionScanner返回的类也实现了“扩展”子接口 例如: public interface A {} public interface B extends A {} public interface C extends A {} public interface D extends A {} public interface E extends B {}

我需要在我的spring boot应用程序中找到只实现一个特定接口的类。 我面临的问题是ClassPathBeanDefinitionScanner返回的类也实现了“扩展”子接口

例如:

public interface A {}

public interface B  extends A {}
public interface C  extends A {}
public interface D  extends A {}

public interface E  extends B {}
public interface F  extends B {}
public interface G  extends B {}
public interface H  extends B {}
public interface I  extends B {}
public interface J  extends B {}
以下是我目前使用的代码:

        BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
        ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr);

        TypeFilter tf_include_1 = new AssignableTypeFilter(E.class);

        TypeFilter tf_exculude1 = new AssignableTypeFilter(C.class);
        TypeFilter tf_exculude2 = new AssignableTypeFilter(D.class);

        s.addIncludeFilter(tf_include_1);

        s.addExcludeFilter(tf_exculude1);
        s.addExcludeFilter(tf_exculude2);

        s.setIncludeAnnotationConfig(false);

//      s.resetFilters(false);
        s.scan("edu.university.ServiceLayer.*");  


        System.out.println("Printing all classes that implement the E");
        String[] beans = bdr.getBeanDefinitionNames();
        for (String string : beans) {
            System.out.println(string);
        }
现在的结果是数组字符串“beans”包含所有其他类,如F、G、H、I、J等

如何以只返回只实现指定接口的选定类的方式构造我的TypeFitler,即过滤掉应用扩展接口的所有实现。例如B类,但E类除外

以下是将ClassPathBeanDefinitionScanner的默认构造函数更改为ClassPathBeanDefinitionScanner(bdr,false)后适用于我的代码,正如用户@Holger所建议的那样

        BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
        ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr, false);

        TypeFilter tf_include_1 = new AssignableTypeFilter(E.class);


        s.resetFilters(false);    

        s.addIncludeFilter(tf_include_1);

        s.setIncludeAnnotationConfig(false);

        s.scan("edu.university.ServiceLayer.*");  


        System.out.println("Printing all classes that implement the E");
        String[] beans = bdr.getBeanDefinitionNames();
        for (String string : beans) {
            System.out.println(string);
        }

请注意,resetFilters已被注释掉,其顺序也已更改

没有任何类型的
C
D
F
G
H
I
J
可分配给
E
,因为它们不是
E
的子类型,因此一个简单的包含筛选器
新的可分配类型筛选器(E.class)
应该可以完成这项工作

您的问题源于使用
新的ClassPathBeanDefinitionScanner(bdr)
构造函数,该构造函数将使用默认过滤器初始化扫描仪,如您所见。虽然将根据所有排除筛选器检查类型,但一个匹配的包含筛选器足以使其显示在结果中。所以你肯定不想要任何其他的,潜在矛盾的,包含过滤器


因此,解决方案是使用构造函数
newclasspathbeandefinitionscanner(bdr,false)

为什么需要这个?从面向对象的角度来看,它们都实现了接口,如果你不想这样,那么首先不要让其他接口扩展接口…只创建一个空的
接口扩展一个{}
,并在感兴趣的bean中实现它,然后扫描
OnlyA
而不是
A
@M.Deinum好吧,为了在我的应用程序中实现服务模型,我使用了策略模式和模板模式。这节省了我大量的输入,但现在我需要找到一个特定的接口,因为它们都是相互扩展的。基本上这就是你问我为什么需要这个的答案。我希望我能以一种特殊的方式构造类型过滤器,只得到一个接口。@Sasha Salauyou如果我再为我的每一个类创建一个这样的接口,就可以克服在代码中使用策略和模板模式的缺点。我需要以接口E为目标。我在想,既然可以排除基本干扰“C”和“D”,也就是只返回扩展了B的接口,那么应该可以这样做。i、 e.只返回e,因为排除是有效的,所以类型过滤器最有可能以某种特定的方式构造。