ServiceLoader (согласно ответу Эриксона), и это будет выглядеть примерно так:
ServiceLoader<Pet> loader = ServiceLoader.load(Pet.class); for (Pet implClass : loader) { System.out.println(implClass.getClass().getSimpleName()); // prints Dog, Cat }
Обратите внимание, что для этого вам нужно определить Petкак ServiceProviderInterface (SPI) и объявить его реализации. вы делаете это, создавая файл в resources/META-INF/services с именем examples.reflections.Pet и объявляя в нем все реализации Pet
examples.reflections.Dog examples.reflections.Cat
аннотация на уровне пакета. вот пример:
Package[] packages = Package.getPackages(); for (Package p : packages) { MyPackageAnnotationannotation= p.getAnnotation(MyPackageAnnotation.class); if (annotation != null) { Class<?>[] implementations = annotation.implementationsOfPet(); for (Class<?> impl : implementations) { System.out.println(impl.getSimpleName()); } } }
Обратите внимание, что только пакеты, которые известны загрузчику классов на данный момент, будут загружены вызовом Package.getPackages().
Кроме того, существуют другие подходы, основанные на URLClassLoader, которые всегда будут ограничены классами, которые уже были загружены, если вы не выполняете поиск по каталогам.
Ответ 2
В общем, это дорого. Чтобы использовать отражение, класс должен быть загружен. Если вы хотите загрузить каждый класс, доступный в classpath, это потребует времени и памяти и не рекомендуется.
Если вы хотите избежать этого, вам нужно будет реализовать свой собственный анализатор файлов классов, который работал бы более эффективно, вместо reflection. Библиотека разработки байтового кода может помочь с этим подходом.
Механизм поставщика услуг является обычным средством перечисления реализаций подключаемого сервиса и стал более устоявшимся с введением Project Jigsaw (модулей) в Java 9. Используйте ServiceLoader в Java 6 или реализуйте свой собственный в более ранних версиях. Я привел пример в другом ответе.
Ответ 3
Что сказал Эриксон, но если вы все еще хотите это сделать, тогда взгляните на Reflections . С их страницы:
Используя отражения, вы можете запросить свои метаданные для:
получить все подтипы некоторого типа
получить все типы, аннотированные некоторой аннотацией
получить все типы, аннотированные некоторой аннотацией, включая соответствие параметров аннотации
получить все методы, аннотированные некоторыми
Ответ 4
У Spring есть довольно простой способ достичь этого: