IoC-контейнер spring и обращение через интерфейсы

189
02 июня 2018, 18:40

Присутствует класс IndexMatrix и он имплемитирует интерфейс IMatrix:

public class IndexMatrix implements IMatrix{
    private int[][] matrix;
    @Override
    public int[][] getMatrix() {
        return matrix;
    }
    @Override
    public void generateMatrix(int sizeX, int sizeY) {
        int mass[][] = new int[sizeX][sizeY];
        for (int i = 1; i <= sizeX; i++){
            for (int j = 1; j <= sizeY; j++){
                mass[i-1][j-1] = (10 * i) + j;
            }
        }
        matrix = mass;
    }
}

Класс Main вызывает класс Menu:

public class Main {
    public static void main(String[] args) throws IOException {
        Menu menu = new Menu();
        menu.start();
    }
}

Как мне в классе Menu нужно реализовать взаимосвязи, что в case 1 дёргался объект IMatrix и после выполнения switch работали методы?

Т.е. как сделать, чтобы находились нужные @Bean и где вообще нужно пометить @Bean? где описть Contex?

switch(number) {
case 1:
                        getQuestion();
                        matrix = IndexMatrix();
                        break;
....
}
....
matrix.generateMatrix(sizeX, sizeY);
printer.print(matrix);
....
@Configurable
@ComponentScan
public class Configuration {
    @Bean(name = "IndexMatrix")
    public IMatrix IndexMatrix() {
        return new IndexMatrix();
    }
    @Bean(name = "Printer")
    public IPrinter Printer() {
        return new Printer();
    }
}
matrix = (IMatrix) context.getBean("IndexMatrix"); //примерно так, но нельзя
                                            //как-то сократить запись?

p.s. формулировка вопроса, как понимаю.

Answer 1

Аннотация @Autowired делает в точности то, что Вам нужно. Для этого нужно настроить IoC Container, чтобы он искал компоненты в Вашем пакете:

@Configuration
@ComponentScan ("your.package")
public class YourConfiguration {
    ...
}
@Component // По умолчанию имя будет "matrix1"
public class Matrix1 implements IMatrix {
    ...
}
@Component
public class Matrix2 implements IMatrix {
    ...
}
@Component
public class Matrix3 implements IMatrix {
    ...
}
public class Menu {
    @Autowired private IMatrix matrix1; // Здесь внедрение будет происходить не по типу, а по имени
    @Autowired private IMatrix matrix2;
    @Autowired private IMatrix matrix3;
    public void doSomething() {
       switch(number) {
          case 1:
             matrix1.someMethod();
             break;
          case 2:
             matrix2.someMethod();
             break;
          case 3:
             matrix3.someMethod();
             break;
       }
    }
}

Как работает аннотация @Autowired: При запуске приложения Spring контейнер будет "сканировать" пакет your.package (который настраивается с помощью аннотации @ComponentScan) на наличие компонентов (Component, Controller, Entity, ...). Если такие имеются, Spring контейнер создаст объект данного класса, внедрив все зависимости (поля помеченные аннотацией @Autowired) и вызвав конструктор по умолчанию.

Разумеется, для того чтобы это все работало необходимо создать объект класса, который реализует один из интерфейсов: BeanFactory или ApplicationContext. Для этого смотрите:

  • Документацию
  • Замечательные видео-уроки (на англ.)

Недостаток использования аннотации @Autowired: Для того, чтобы указать Spring контейнеру управлять объектом класса Вы используете одну из аннотаций (Component, Controller, Service, ...) на класс. К сожалению, если Вам нужно несколько объектов одного класса аннотация @Autowired Вам не подходит. В данном случае определять компоненты нужно в xml-файле, указывая Qualifier для каждого компонента одного и того же класса:

<bean id="..." class="...">
   <qualifier value="qualifierName" />
   ...
</bean>

Далее внедрить компонент можно следующим образом:

@Autowired 
@Qualifier("qualifierName")
private YourClass clazz;
READ ALSO
Сохранение и вывод данных

Сохранение и вывод данных

Есть 3 поля с даными, вводимыми пользователями: имя, дата рождения, место рождениянадо записать эти данные в файл а потом из файла запихнуть...

209
Spring Value: почему некорректно видит переменные?

Spring Value: почему некорректно видит переменные?

Я вынес все данные в properties, например, с такими полями:

183
Привязать jscrollbar

Привязать jscrollbar

Как привязать jscrollbar к панели в визуальном редакторе intellij? Находил только примеры с добавлением в коде, нужно именно в редакторе

183
Как выводить базу данных через ListView Java [закрыт]

Как выводить базу данных через ListView Java [закрыт]

Есть база данных, созданная с помощью SQL, в ней есть таблица с четырьмя полями, нужно вывести их на экран активности используя ListView

224