Frostman's blog

Blog about programming and techs

JC13 - Lecture 05. DI & Annotations

Mirantis Java Сourse 2013 (back)

Lecture 05. DI & Annotations

Java Class Loaders

Практическое задание (на занятии) #1 / Домашнее задание

Необходимо реализовать простейший DI (Dependency Injection) фреймворк.

Аннотация @Inject:

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Inject {
    public static final String DEFAULT_NAME = "";

    String value() default DEFAULT_NAME;
}
  • Поля помеченные @Inject должны быть автоматически инициализированны с использованием инжектора;
  • если указано имя объекта - @Inject("test-str"), то должен грузиться объект, зарегистрированный под именем "test-str".

Методы класса Injector:

  • public static <T> T getInstance(Class<T> clazz) - получить представителя указанного объекта, в котором все поля помеченные аннотацие тоже проинициализированны с использованием этого метода или перегруженного варианта с дополнительным аргументом - именем объекта;
  • public static <T> T getInstance(Class<T> clazz, String name);
  • public static void bind(Class<T> clazz, T value) - регистрация конкретного значения для указанного класса (вместо инстанциирования каждый раз);
  • public static void bind(Class<T> clazz, T value, String name).

Пример:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Sample {
    public static void main(String[] args) {
        Injector.bind(String.class, "str-default-value");
        Injector.bind(String.class, "str-a-value", "str-a");
        B val = Injector.getInstance(B.class);
        System.out.println(val); // [ba=[a='str-a-value', b='str-default-value']]
    }
}

class A {
    @Inject("str-a")
    private String a; // Injector.getInstance(String.class, "str-a")

    @Inject
    private String b; // Injector.getInstance(String.class)

    @Override
    public String toString() {
        return "[a='" + a + "', b='" + b + "']";
    }
}

class B extends A {
    @Inject
    private A ba; // Injector.getInstance(A.class)

    @Override
    public String toString() {
        return "[ba=" + super.toString() + "]";
    }
}