Как внедрение зависимостей вручную? - PullRequest
6 голосов
/ 21 августа 2010

Как мы можем вручную ввести объект, не используя средство контейнеров.Я сделал нечто подобное с помощью отражения следующим образом.

Class actionClass = Class.forName("SampleClass");
Object actionObject = actionClass.newInstance();
Method reqMethod = actionClass.getMethod("setRequest", HttpServletRequest.class);
reqMethod.invoke(actionObject,request);

это правильный способ сделать DI?

Я хочу динамически передавать объект запроса в различные классы контроллера из фильтра диспетчера,где мы получаем объекты запроса и ответа.Я боюсь за качество отражения. Есть ли какая-нибудь замена для выполнения DI?

Ответы [ 5 ]

5 голосов
/ 21 августа 2010

Внедрение зависимостей - это не что иное, как предоставление классу его зависимостей, а не то, чтобы он сам находил их (через синглтоны / поиски и т.д.). Таким образом, вы можете сделать это в коде тривиально:

DatabaseConnection dc = new DatabaseConnection();
MyDAO dao = new MyDAO(dc);

(псевдокод). Здесь MyDAO вводится с подключением к базе данных. Если это соединение с базой данных реализует интерфейс, вы можете легко смоделировать это во время тестирования.

2 голосов
/ 21 августа 2010

Что ж, когда вы устанавливаете один объект в другой, используя метод установки или через конструктор, это также является внедрением зависимости.Внедрение зависимостей означает только создание отношений (зависимостей) в объектах.

Использование отражения, как вы это сделали, является еще одной его формой.

1 голос
/ 21 августа 2010

Зачем вам использовать отражение?Почему бы просто:

SampleClass action = new SampleClass();
action.setRequest(request);

Это делает то же самое, но более читабельно, позволяет компилятору проверить, что типы и методы действительно существуют, предоставляет вам Javadoc для вызванного метода, позволяет вашей IDEпомочь в рефакторинге, ...

И все же это внедрение зависимостей, потому что действие не ищет его запрос, а получает запрос во время инициализации.

Редактировать : Турбьёрн попросил показать, как будет использоваться это действие.Само по себе оно будет введено (с помощью установщика) в любой компонент, использующий действие.Компонент будет использовать внедренный объект действия.

SampleClass action = new SampleClass();
action.setRequest(request);
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);

Если servlet предназначен для жизни дольше, чем action, то есть он должен использовать новый Action каждый раз, когда ему это нужно, можновместо этого setter-inject ActionFactory в servlet.

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

SampleClass action = new SampleClass();
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);

и ActionBasedServlet определят

public void serve(Request req, Response resp) {
    foo();
    action.act(req, resp);
    bar();
}
0 голосов
/ 04 января 2012

Spring Framework - одна из самых популярных реализаций DI.Это также с открытым исходным кодом.Вы можете проверить класс org.springframeowrk.beans.BeanUtils, в частности методы copyProperties (все 4 из них) для примеров того, как это сделать.Для получения дополнительной информации вы также можете увидеть иерархию классов org.springframework.beans.factory.BeanFactory для различных стратегий.

0 голосов
/ 21 августа 2010

Внедрение зависимостей подразумевает, что вы получаете правильно инициализированные ссылки, появляющиеся «по волшебству».

Вы вызываете метод setRequest () с объектом запроса, но DI часто также позволяет устанавливать поля без вызова методов.

Guice как таковой не требует контейнера, но использует магию загрузчика классов, запущенную в методе main.Будет ли это полезно для вас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...