Создание объекта по его пути, полученному из свойства аннотации - PullRequest
0 голосов
/ 26 октября 2011

1. Имеют следующую аннотацию:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Trackable {
    String builder();
}

2. использование этой аннотации:

@Trackable(builder = "pkg1.SomeVO")
public class MyService

3. pkg1.SomeVO - это путь к объекту Java, который должен быть реализован в моем классе аспектов.

4. У меня есть строковое значение build, равное 'pkg1.SomeVO' от отражения.

Вопрос в том, как на самом деле создать SomeVO объект?
Мне нужно это как:
MyBuilder mb=new SomeVO(); где MyBuilder является абстрактным классом, уже определенным.

Это может быть любой объект, e. г. SomeVO2 и т. Д., Поэтому я определенно не знаю в моем аспекте (см. Шаг 3), какой класс должен быть создан.

Ответы [ 2 ]

2 голосов
/ 26 октября 2011

Сделайте что-то подобное, чтобы получить значение аннотации и создать класс. Кроме того, вы можете использовать поле значений по умолчанию и Class вместо String в своих аннотациях, чтобы упростить задачу.

for (Method m : MyService.class.getDelcaredMethods())
  if (m.getAnnotation(Trackable.class) != null) {
      String className = m.getAnnotation(Trackable.class).builder()
      Class.forName(className).newInstance();
  }

Если в вашем классе нет конструктора по умолчанию, вам нужно выяснить, какие аргументы ему нужны:

for (Constructor c : Class.forName(className).getConstructors())
   if (c.getParameterTypes() == /* your expected arg types */)
       return c.newInstance(/* your args */);

Чтобы убедиться, что ваш класс относится к определенному типу (например, MyBuilder), вы можете сделать свою аннотацию:

public @interface Trackable {
   Class<? extends MyBuilder> value()
}
0 голосов
/ 26 октября 2011

Предполагая под путем, вы имеете в виду пакет, в котором находится ваш класс (который, мы надеемся, находится на пути к классам).

String myClass = getClassNameFromAnnotationReflectively(); // YOU define this method...
Class<SomeVO> someVoClass = Class.forName(myClass);
SomeVO someVo = someVoClass.newInstance();

Если ваш class не имеет конструктора по умолчанию, вы можете найти правильный, используя getConstructor(Class<?> ...) (где вы передаете типы аргументов конструктора, который вы ищете) и затем вызывая newInstance(Object...) (передавая фактические значения).

Существует множество забавных методов для использования на объекте Class. Я рекомендую взглянуть.

...