Методы получения метаданных аннотаций в Java

Я работаю над структурой проверки JSR-303 для GWT. Некоторые из вас, возможно, слышали об этом, хотя это небольшой проект. Вот проверка gwt.

В старые времена (v1.0) он использовал интерфейс маркера для каждого класса, и метаданные каждого класса генерировались отдельно. Это было плохо, потому что это не было частью стандарта JSR-303, и мы перешли к следующей идее.

В версии 2.0 он сканирует путь к классам во время выполнения, используя Reflections. Отлично. Недостатком является то, что он, похоже, не может работать внутри контейнерных сред или сред с особыми ограничениями.

Вероятно, это моя вина, посмотрите на следующий код:

    //this little snippet goes through the classpath urls and ommits jars that are on the forbidden list.
    //this is intended to remove jars from the classpath that we know are not ones that will contain patterns
    Set<URL> classPathUrls = ClasspathHelper.forJavaClassPath();
    Set<URL> useableUrls = new HashSet<URL>();
    for(URL url : classPathUrls) {
        boolean use = true;
        for(String jar : this.doNotScanJarsInThisList) {
            if(url.toString().contains(jar)) {
                use = false;
                break;
            }
        }
        if(use) {
            useableUrls.add(url);
        }
        use = false;
    }       

    ConfigurationBuilder builder = new ConfigurationBuilder()
                                    .setUrls(useableUrls)
                                    .setScanners(   new TypeAnnotationsScanner(), 
                                                    new FieldAnnotationsScanner(), 
                                                    new MethodAnnotationsScanner(), 
                                                    new SubTypesScanner()
                                    )
                                    .useParallelExecutor()
                                    ;

    this.reflections = new Reflections(builder);

Я использую фильтр для удаления банок, которые, как я знаю, не могут содержать интересующие меня аннотации. Как я уже упоминал, это дает огромный прирост скорости (особенно на больших путях к классам), но ClasspathHelper.forJavaClassPath(), на котором я основываюсь, вероятно, не лучший способ работать в средах контейнеров. (например, Tomcat, JBoss)

Есть ли лучший способ или, по крайней мере, способ, который будет работать с контейнерной средой и при этом позволит моим пользователям отфильтровывать классы, которые им не нужны?

Я просмотрел, некоторые, как проект Hibernate Validation (эталонная реализация для JSR-303), и они, по крайней мере, используют (по крайней мере, частично) обработку аннотаций в Java 6. Это не может быть все история, потому что это не появлялось до тех пор, пока JDK6 и Hibernate Validator не будут совместимы с JDK5. (См.: документацию по гибернации. )

Так что, как всегда, это еще не все.

Я читал эти темы, для справки:

  • О сканировании, которое в значительной степени было заменено отражениями.
  • Этот один, но он использует файл, и я не уверен, каковы последствия этого в таких вещах, как GAE (Google App Engine) или Tomcat.
  • Еще один который идет дальше многих вещей, о которых я уже говорил.

Эти темы только помогли так много.

Я также прочитал о структуре обработки аннотаций, и я, должно быть, что-то упустил. Кажется, он делает то, что я хочу, но опять же, похоже, он работает только во время компиляции, что, как я знаю, не то, что делает Hibernate Validator. (Кто-нибудь может объяснить, как он выполняет сканирование? Он работает в GAE, что означает, что он не может использовать какие-либо пакеты ввода-вывода.)

Кроме того, будет ли этот код работать лучше, чем тот, что у меня выше?

Set<URL> classPathUrls = ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader());

Может ли это правильно получить загрузчик классов внутри контейнера Tomcat или JBoss? Кажется, отсканируйте меньший набор классов и все равно закончите нормально.

Итак, в любом случае, может ли кто-нибудь помочь мне указать правильное направление? Или я просто застрял с тем, что у меня есть?


person Chris Ruffalo    schedule 08.12.2011    source источник


Ответы (1)


Вы можете взглянуть на поддержку аннотаций Spring. Spring может сканировать аннотации в файлах (используя asm IIRC) и работает в контейнере и вне его.

Это может быть непросто, потому что он проходит через абстракцию ресурсов Spring, но он должен быть выполним для повторного использования (или извлечения) соответствующего кода.

person Olivier Croisier    schedule 09.12.2011