Я работаю над структурой проверки 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? Кажется, отсканируйте меньший набор классов и все равно закончите нормально.
Итак, в любом случае, может ли кто-нибудь помочь мне указать правильное направление? Или я просто застрял с тем, что у меня есть?