SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Downloaden Sie, um offline zu lesen
Dependency Injection в Java
на примере эволюции
Spring – Guice – CDI/Weld
Сергей Кошель
Ведущий разработчик Java
23 мая 2013 года
Разрабатываем адаптер
Преобразование
2/36
Первая версия
SimpleConverter
FileSource DatabaseStorage
Adapter
3/36
Первая версия
+ Работать будет
− Невозможно написать unit-тест
public class Adapter {
public void processMessage() {
final FileSource fileSource = new FileSource();
final SimpleConverter simpleConverter = new SimpleConverter();
final DatabaseStorage databaseStorage = new DatabaseStorage();
final Message inputMessage = fileSource.getMessage();
final Message convertedMessage = simpleConverter.convert(inputMessage);
databaseStorage.store(convertedMessage);
}
}
4/36
Выделяем интерфейсы
MockConverter
MockSource MockStorage
FileSource
SimpleConverter
DatabaseStorage
Source
Converter
Storage
Adapter 5/36
И добавляем фабрики
public class Adapter {
public void processMessage() {
final Source source = SourceFactory.getSource();
final Converter converter = ConverterFactory.getConverter();
final Storage storage = StorageFactory.getStorage();
final Message inputMessage = source.getMessage();
final Message convertedMessage = converter.convert(inputMessage);
storage.store(convertedMessage);
}
}
6/36
Пишем тест
@Test
public void processMessage() throws Exception {
SourceFactory.setSource(new MockSource("Hello from test!"));
StorageFactory.setStorage(new MockStorage());
final Adapter adapter = new Adapter();
adapter.processMessage();
// assert that...
}
+ Получилось написать тест
− Статический (глобальный) контекст
− Много бойлерплейта
− Зависимости неочевидны
7/36
Избавляемся от фабрик
public class Adapter {
private Source source;
private Converter converter;
private Storage storage;
public void setSource(Source source) {…}
public void setConverter(Converter converter) {…}
public void setStorage(Storage storage) {…}
public void processMessage() {
final Message inputMessage = source.getMessage();
final Message convertedMessage = converter.convert(inputMessage);
storage.store(convertedMessage);
}
}
8/36
Переписываем тест
@Test
public void processMessage() throws Exception {
final Adapter adapter = new Adapter();
adapter.setSource(new MockSource("Hello from test!"));
adapter.setConverter(new SimpleConverter());
adapter.setStorage(new MockStorage());
adapter.processMessage();
// assert that...
}
+ Получилось:
Setter based Dependency Injection by Hand
9/36
Последний штрих
public class Adapter {
private final Source source;
private final Converter converter;
private final Storage storage;
public Adapter(Source source, Converter converter, Storage storage) {
this.source = source;
this.converter = converter;
this.storage = storage;
}
public void processMessage() {…}
}
10/36
Dependency Injection (DI)
 Паттерн проектирования (design pattern)
 О компонентах и их зависимостях
 Позволяет отделить объявление
зависимости от разрешения зависимости
(и в пространстве, и во времени)
 Является частью более общего принципа
Inversion of Control (Hollywood principle –
«Don't call us, we'll call you».)
11/36
Причем тут тесты?
 Тесты не самоцель, но…
 С одной стороны, практически,
DI позволяет проще писать
тестопригодный код
 А с другой стороны, концептуально,
тесторигодность кода является
индикатором хорошей слабосвязанной
архитектуры (loose coupling)
 В конечном итоге DI помогает удобнее
писать слабосвязный код
12/36
Можно было пойти другим путем
public class Adapter {
public void processMessage() {
final Source source = UniversalFactory.get("source", Source.class);
final Converter converter = UniversalFactory.get("converter",
Converter.class);
final Storage storage = UniversalFactory.get("storage", Storage.class);
final Message inputMessage = source.getMessage();
final Message convertedMessage = converter.convert(inputMessage);
storage.store(convertedMessage);
}
}
+ Получилось: Service Locator
13/36
Паттерны DI и SL
часто противопоставляются
DI зависимости определяет статически
 Проще разобраться в связях
 Компилятор многое может проверить
и подсказать
 Но иногда это является ограничением
SL – динамически
 Взаимосвязи запутаны, проще ошибиться
 Но иногда без этого не обойтись
14/36
IoC-контейнер
Автоматизирует DI
 Разрешает граф зависимостей
 Конструирует компоненты по метаописанию
зависимостей
И привносит еще много полезностей
 Управление жизненным циклом
 Управление конфигурацией
 AOP
 …
15/36
Disclaimer
Автор не в коем случае не имеет
цели принизить один фреймворк
за счет другого
16/36
Spring Framework
17/36
Описываем зависимости
<?xml version="1.0" encoding="UTF-8"?>
<beans …>
<bean id="adapter" class="custis.seminars.diinjava.spring.Adapter" >
<property name="source" ref="source"/>
<property name="converter" ref="converter"/>
<property name="storage" ref="storage"/>
</bean>
<bean id="source" class="custis.seminars.diinjava.spring.FileSource" />
<bean id="converter" class="custis.seminars.diinjava.spring.SimpleConverter"
/>
<bean id="storage" class="custis.seminars.diinjava.spring.DatabaseStorage"
/>
</beans>
* Похоже на императив, но это декларатив
18/36
Запускаем контейнер
final ApplicationContext applicationContext
= new ClassPathXmlApplicationContext("spring-config.xml");
adapter = applicationContext.getBean("adapter", Adapter.class);
+ Код адаптера не изменился
+ …нет зависимости от Spring’а
+ …не надо его писать в каком-либо
специальном стиле
19/36
Autowiring
<bean id="adapter" class="custis.seminars.diinjava.autowiring.Adapter"
autowire="byType" />
20/36
Lifecycle Management
 singleton – создается один экземпляр
 prototype – создается отдельный экземпляр
при каждом обращении
<bean id="adapter" class="custis.seminars.diinjava.autowiring.Adapter"
autowire="byType"
scope="singleton"
init-method="init"
destroy-method="close" />
[…]
applicationContext.destroy();
21/36
Метаданные в компоненте
@Scope(SCOPE_SINGLETON)
public class Adapter {
private Source source;
private Converter converter;
private Storage storage;
@Autowired
public void setSource(Source source) {…}
@Autowired
public void setConverter(Converter converter) {…}
@Autowired(required = false)
public void setStorage(Storage storage) {…}
@PostConstruct
public void init() {…}
@PreDestroy
public void close() {…}
} 22/36
Выбор
между несколькими реализациями
23/36
<bean id="source" class="custis.seminars.diinjava.autowiring.FileSource" />
@Autowired
@Qualifier("source")
public void setSource(Source source) {…}
− Легко ошибиться, и проявится это только в рантайме
Google Guice
24/36
Pure Java config
public class AdapterModule extends AbstractModule {
@Override
protected void configure() {
bind(SimpleConverter.class);
bind(Source.class).to(FileSource.class);
bind(Storage.class).toInstance(new DatabaseStorage());
}
}
final Injector injector = Guice.createInjector(new AdapterModule());
adapter = injector.getInstance(Adapter.class);
25/36
Annotation based
@Singleton
public class Adapter {
private final Source source;
private final Converter converter;
private final Storage storage;
@Inject
public Adapter(Source source, Converter converter, Storage storage) {
this.source = source;
this.converter = converter;
this.storage = storage;
}
public void processMessage() {…}
}
* Зависимость от аннотаций, но они стандартные
26/36
Pure Java config
public class AdapterModule extends AbstractModule {
@Override
protected void configure() {…}
@Provides
Source fileSource() {
return new FileSource();
}
}
* В Spring 3.0 появился JavaConfig
27/36
Provider interface
public interface Provider <T> {
T get();
}
bind(Validator.class).to(SimpleValidator.class);
public class Adapter {
private Provider<Validator> validator;
@Inject
public void setValidator(Provider<Validator> validator) {…}
public void processMessage() {
...
validator.get().validate(inputMessage);
...
}
}
28/36
Provider interface
Когда нужно…
 отложить создание (тяжелое, условное)
 много экземпляров (the new «new»)
 вложить более узкий скоуп в широкий
29/36
Выбор
между несколькими реализациями
30/36
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface FileBased {}
@Inject
public Adapter(@FileBased Source source, Converter converter, Storage storage) {…}
bind(Source.class).annotatedWith(FileBased.class).to(FileSource.class);
+ Typesafe – компилятор проверит
CDI/Weld
JSR 299: Contexts and Dependency Injection
for the Java EE platform
Weld – reference implementation
for JSR-299
31/36
CDI
 Конфигурация похожа на Guice
 Нет DSL — используется @Produce
и сканирование classpath
 Стандартизирует @Inject, @Sengleton,
Provider<T> и т. д.
 Тесно интегрируется с EJB-контейнером
32/36
Instance – Provider на стероидах
 Расширяет возможности Provider
Instance<T> extends Provider<T>
 …опциональные зависимости
if (instance.isUnsatisfied()) {…}
 …многозначные зависимости
if (instance.isAmbiguous()) {
for (T t : instance) {...}
}
 …динамическое разрешение зависимостей (SL)
adapter = instance.select(Adapter.class).get();
33/36
Event<T>
public class Adapter {
@Inject
Event<AdapterStarted> adapterStartedEvent;
@PostConstruct
public void init() {
adapterStartedEvent.fire(new AdapterStarted());
}
}
public class AnyOtherManagedBean{
public void onAdapterStart(
@Observes AdapterStarted adapterStarted) {…}
}
34/36
О чем не рассказал
 AOP и method intercepting
 Генерализованные типы зависимостей
 Многозначные зависимости
 Scopes
 …
35/36
Спасибо!
Вопросы?
Сергей Кошель
skoshel@custis.ru
36/36

Weitere ähnliche Inhalte

Was ist angesagt?

Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.Igor Shkulipa
 
Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. DatabasesSergey Nemchinsky
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4Technopark
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.Igor Shkulipa
 
Аспектно-ориентированное программирование в распределенных системах для java ...
Аспектно-ориентированное программирование в распределенных системах для java ...Аспектно-ориентированное программирование в распределенных системах для java ...
Аспектно-ориентированное программирование в распределенных системах для java ...Igor Suhorukov
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
C++ весна 2014 лекция 5
C++ весна 2014 лекция 5C++ весна 2014 лекция 5
C++ весна 2014 лекция 5Technopark
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.Igor Shkulipa
 
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...vitaliykulanov
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.Igor Shkulipa
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5Technopark
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Victor_Cr
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.Igor Shkulipa
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8Technopark
 
C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.Igor Shkulipa
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.Igor Shkulipa
 
C++ осень 2013 лекция 6
C++ осень 2013 лекция 6C++ осень 2013 лекция 6
C++ осень 2013 лекция 6Technopark
 
Candidates for-php-developers-tests
Candidates for-php-developers-testsCandidates for-php-developers-tests
Candidates for-php-developers-testsguest5fa21c
 

Was ist angesagt? (20)

Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.
 
Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. Databases
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
Аспектно-ориентированное программирование в распределенных системах для java ...
Аспектно-ориентированное программирование в распределенных системах для java ...Аспектно-ориентированное программирование в распределенных системах для java ...
Аспектно-ориентированное программирование в распределенных системах для java ...
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
C++ весна 2014 лекция 5
C++ весна 2014 лекция 5C++ весна 2014 лекция 5
C++ весна 2014 лекция 5
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.
 
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...
Basic principles of projects description in VHDL - ENTITY, ARCHITECTURE, LIBR...
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5
 
Tdd php
Tdd phpTdd php
Tdd php
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8
 
C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.
 
C++ осень 2013 лекция 6
C++ осень 2013 лекция 6C++ осень 2013 лекция 6
C++ осень 2013 лекция 6
 
Candidates for-php-developers-tests
Candidates for-php-developers-testsCandidates for-php-developers-tests
Candidates for-php-developers-tests
 

Andere mochten auch

Аналитические планы счетов как архитектурный артефакт
Аналитические планы счетов как архитектурный артефактАналитические планы счетов как архитектурный артефакт
Аналитические планы счетов как архитектурный артефактCUSTIS
 
CDI Best Practices with Real-Life Examples - TUT3287
CDI Best Practices with Real-Life Examples - TUT3287CDI Best Practices with Real-Life Examples - TUT3287
CDI Best Practices with Real-Life Examples - TUT3287Ahmad Gohar
 
Будущее omni-channel маркетинга: инструменты, кейсы и цифры
Будущее omni-channel маркетинга: инструменты, кейсы и цифрыБудущее omni-channel маркетинга: инструменты, кейсы и цифры
Будущее omni-channel маркетинга: инструменты, кейсы и цифрыCUSTIS
 
JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6Bert Ertman
 
Java EE and Spring Side-by-Side
Java EE and Spring Side-by-SideJava EE and Spring Side-by-Side
Java EE and Spring Side-by-SideReza Rahman
 

Andere mochten auch (6)

Аналитические планы счетов как архитектурный артефакт
Аналитические планы счетов как архитектурный артефактАналитические планы счетов как архитектурный артефакт
Аналитические планы счетов как архитектурный артефакт
 
CDI Best Practices with Real-Life Examples - TUT3287
CDI Best Practices with Real-Life Examples - TUT3287CDI Best Practices with Real-Life Examples - TUT3287
CDI Best Practices with Real-Life Examples - TUT3287
 
Будущее omni-channel маркетинга: инструменты, кейсы и цифры
Будущее omni-channel маркетинга: инструменты, кейсы и цифрыБудущее omni-channel маркетинга: инструменты, кейсы и цифры
Будущее omni-channel маркетинга: инструменты, кейсы и цифры
 
Chapter6
Chapter6Chapter6
Chapter6
 
JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6
 
Java EE and Spring Side-by-Side
Java EE and Spring Side-by-SideJava EE and Spring Side-by-Side
Java EE and Spring Side-by-Side
 

Ähnlich wie Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld

C# Desktop. Занятие 12.
C# Desktop. Занятие 12.C# Desktop. Занятие 12.
C# Desktop. Занятие 12.Igor Shkulipa
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноCUSTIS
 
C# Desktop. Занятие 06.
C# Desktop. Занятие 06.C# Desktop. Занятие 06.
C# Desktop. Занятие 06.Igor Shkulipa
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8Technopark
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.Doomer Samoiloff
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.Igor Shkulipa
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CYandex
 
Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesbeloslab
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Andrey Rebrov
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...Ontico
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf Conference
 
Принципы проектирования S.O.L.I.D
Принципы проектирования S.O.L.I.DПринципы проектирования S.O.L.I.D
Принципы проектирования S.O.L.I.DAndreyGeonya
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый стартAntonio
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8chashnikov
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.Igor Shkulipa
 
Помоги ближнему, или Как потоки помогают друг другу
Помоги ближнему, или Как потоки помогают друг другуПомоги ближнему, или Как потоки помогают друг другу
Помоги ближнему, или Как потоки помогают друг другуAlexey Fyodorov
 

Ähnlich wie Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld (20)

C# Desktop. Занятие 12.
C# Desktop. Занятие 12.C# Desktop. Занятие 12.
C# Desktop. Занятие 12.
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдно
 
C# Desktop. Занятие 06.
C# Desktop. Занятие 06.C# Desktop. Занятие 06.
C# Desktop. Занятие 06.
 
Zend framework 2
Zend framework 2Zend framework 2
Zend framework 2
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.
 
Cloud Haskell. Александр Вершилов
Cloud Haskell. Александр ВершиловCloud Haskell. Александр Вершилов
Cloud Haskell. Александр Вершилов
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
 
Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practices
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
 
Принципы проектирования S.O.L.I.D
Принципы проектирования S.O.L.I.DПринципы проектирования S.O.L.I.D
Принципы проектирования S.O.L.I.D
 
Design Principles
Design PrinciplesDesign Principles
Design Principles
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый старт
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.
 
Помоги ближнему, или Как потоки помогают друг другу
Помоги ближнему, или Как потоки помогают друг другуПомоги ближнему, или Как потоки помогают друг другу
Помоги ближнему, или Как потоки помогают друг другу
 

Mehr von CUSTIS

Три истории микросервисов, или MSA для Enterprise
Три истории микросервисов, или MSA для EnterpriseТри истории микросервисов, или MSA для Enterprise
Три истории микросервисов, или MSA для EnterpriseCUSTIS
 
Долгоживущие ИТ в динамичном ритейле
Долгоживущие ИТ в динамичном ритейлеДолгоживущие ИТ в динамичном ритейле
Долгоживущие ИТ в динамичном ритейлеCUSTIS
 
Будущее уже наступило: от Agile к бирюзовым организациям
Будущее уже наступило: от Agile к бирюзовым организациямБудущее уже наступило: от Agile к бирюзовым организациям
Будущее уже наступило: от Agile к бирюзовым организациямCUSTIS
 
Как выбрать для проекта практики проектирования и работы с требованиями
Как выбрать для проекта практики проектирования и работы с требованиямиКак выбрать для проекта практики проектирования и работы с требованиями
Как выбрать для проекта практики проектирования и работы с требованиямиCUSTIS
 
Диаграммы учета как средство для наглядного и целостного отображения правил у...
Диаграммы учета как средство для наглядного и целостного отображения правил у...Диаграммы учета как средство для наглядного и целостного отображения правил у...
Диаграммы учета как средство для наглядного и целостного отображения правил у...CUSTIS
 
Сотрудничество с корпорациями: рецепты из практики
Сотрудничество с корпорациями: рецепты из практикиСотрудничество с корпорациями: рецепты из практики
Сотрудничество с корпорациями: рецепты из практикиCUSTIS
 
Agile — ответ на вызовы третьей промышленной революции
Agile — ответ на вызовы третьей промышленной революцииAgile — ответ на вызовы третьей промышленной революции
Agile — ответ на вызовы третьей промышленной революцииCUSTIS
 
Опыт построения микросервисной архитектуры в цифровом банке
Опыт построения микросервисной архитектуры в цифровом банкеОпыт построения микросервисной архитектуры в цифровом банке
Опыт построения микросервисной архитектуры в цифровом банкеCUSTIS
 
Золотая лихорадка MSA: почему нам не подошли микросервисы?
Золотая лихорадка MSA: почему нам не подошли микросервисы?Золотая лихорадка MSA: почему нам не подошли микросервисы?
Золотая лихорадка MSA: почему нам не подошли микросервисы?CUSTIS
 
Барьеры микросервисной архитектуры
Барьеры микросервисной архитектурыБарьеры микросервисной архитектуры
Барьеры микросервисной архитектурыCUSTIS
 
Три истории микросервисов
Три истории микросервисовТри истории микросервисов
Три истории микросервисовCUSTIS
 
От монолитных моделей предметной области — к модульным
От монолитных моделей предметной области — к модульнымОт монолитных моделей предметной области — к модульным
От монолитных моделей предметной области — к модульнымCUSTIS
 
Проблемы управления правами доступа к информационным системам крупной торгово...
Проблемы управления правами доступа к информационным системам крупной торгово...Проблемы управления правами доступа к информационным системам крупной торгово...
Проблемы управления правами доступа к информационным системам крупной торгово...CUSTIS
 
Agile и управление знаниями в ИТ-проектах
Agile и управление знаниями в ИТ-проектахAgile и управление знаниями в ИТ-проектах
Agile и управление знаниями в ИТ-проектахCUSTIS
 
State of the .Net Performance
State of the .Net PerformanceState of the .Net Performance
State of the .Net PerformanceCUSTIS
 
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделять
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделятьОтветственность за качество в разных ИТ-проектах: в чем она и как ее разделять
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделятьCUSTIS
 
Опыт применения метода ATAM для оценки архитектуры
Опыт применения метода ATAM для оценки архитектурыОпыт применения метода ATAM для оценки архитектуры
Опыт применения метода ATAM для оценки архитектурыCUSTIS
 
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватает
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватаетГибридный подход к управлению правами доступа: когда стандартного IDM не хватает
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватаетCUSTIS
 
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...CUSTIS
 
Process и Case Management в информационной системе: от автоматизации As Is к ...
Process и Case Management в информационной системе: от автоматизации As Is к ...Process и Case Management в информационной системе: от автоматизации As Is к ...
Process и Case Management в информационной системе: от автоматизации As Is к ...CUSTIS
 

Mehr von CUSTIS (20)

Три истории микросервисов, или MSA для Enterprise
Три истории микросервисов, или MSA для EnterpriseТри истории микросервисов, или MSA для Enterprise
Три истории микросервисов, или MSA для Enterprise
 
Долгоживущие ИТ в динамичном ритейле
Долгоживущие ИТ в динамичном ритейлеДолгоживущие ИТ в динамичном ритейле
Долгоживущие ИТ в динамичном ритейле
 
Будущее уже наступило: от Agile к бирюзовым организациям
Будущее уже наступило: от Agile к бирюзовым организациямБудущее уже наступило: от Agile к бирюзовым организациям
Будущее уже наступило: от Agile к бирюзовым организациям
 
Как выбрать для проекта практики проектирования и работы с требованиями
Как выбрать для проекта практики проектирования и работы с требованиямиКак выбрать для проекта практики проектирования и работы с требованиями
Как выбрать для проекта практики проектирования и работы с требованиями
 
Диаграммы учета как средство для наглядного и целостного отображения правил у...
Диаграммы учета как средство для наглядного и целостного отображения правил у...Диаграммы учета как средство для наглядного и целостного отображения правил у...
Диаграммы учета как средство для наглядного и целостного отображения правил у...
 
Сотрудничество с корпорациями: рецепты из практики
Сотрудничество с корпорациями: рецепты из практикиСотрудничество с корпорациями: рецепты из практики
Сотрудничество с корпорациями: рецепты из практики
 
Agile — ответ на вызовы третьей промышленной революции
Agile — ответ на вызовы третьей промышленной революцииAgile — ответ на вызовы третьей промышленной революции
Agile — ответ на вызовы третьей промышленной революции
 
Опыт построения микросервисной архитектуры в цифровом банке
Опыт построения микросервисной архитектуры в цифровом банкеОпыт построения микросервисной архитектуры в цифровом банке
Опыт построения микросервисной архитектуры в цифровом банке
 
Золотая лихорадка MSA: почему нам не подошли микросервисы?
Золотая лихорадка MSA: почему нам не подошли микросервисы?Золотая лихорадка MSA: почему нам не подошли микросервисы?
Золотая лихорадка MSA: почему нам не подошли микросервисы?
 
Барьеры микросервисной архитектуры
Барьеры микросервисной архитектурыБарьеры микросервисной архитектуры
Барьеры микросервисной архитектуры
 
Три истории микросервисов
Три истории микросервисовТри истории микросервисов
Три истории микросервисов
 
От монолитных моделей предметной области — к модульным
От монолитных моделей предметной области — к модульнымОт монолитных моделей предметной области — к модульным
От монолитных моделей предметной области — к модульным
 
Проблемы управления правами доступа к информационным системам крупной торгово...
Проблемы управления правами доступа к информационным системам крупной торгово...Проблемы управления правами доступа к информационным системам крупной торгово...
Проблемы управления правами доступа к информационным системам крупной торгово...
 
Agile и управление знаниями в ИТ-проектах
Agile и управление знаниями в ИТ-проектахAgile и управление знаниями в ИТ-проектах
Agile и управление знаниями в ИТ-проектах
 
State of the .Net Performance
State of the .Net PerformanceState of the .Net Performance
State of the .Net Performance
 
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделять
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделятьОтветственность за качество в разных ИТ-проектах: в чем она и как ее разделять
Ответственность за качество в разных ИТ-проектах: в чем она и как ее разделять
 
Опыт применения метода ATAM для оценки архитектуры
Опыт применения метода ATAM для оценки архитектурыОпыт применения метода ATAM для оценки архитектуры
Опыт применения метода ATAM для оценки архитектуры
 
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватает
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватаетГибридный подход к управлению правами доступа: когда стандартного IDM не хватает
Гибридный подход к управлению правами доступа: когда стандартного IDM не хватает
 
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...
Собираем кубик Рубика: восстановление архитектурного описания корпоративной р...
 
Process и Case Management в информационной системе: от автоматизации As Is к ...
Process и Case Management в информационной системе: от автоматизации As Is к ...Process и Case Management в информационной системе: от автоматизации As Is к ...
Process и Case Management в информационной системе: от автоматизации As Is к ...
 

Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld

  • 1. Dependency Injection в Java на примере эволюции Spring – Guice – CDI/Weld Сергей Кошель Ведущий разработчик Java 23 мая 2013 года
  • 4. Первая версия + Работать будет − Невозможно написать unit-тест public class Adapter { public void processMessage() { final FileSource fileSource = new FileSource(); final SimpleConverter simpleConverter = new SimpleConverter(); final DatabaseStorage databaseStorage = new DatabaseStorage(); final Message inputMessage = fileSource.getMessage(); final Message convertedMessage = simpleConverter.convert(inputMessage); databaseStorage.store(convertedMessage); } } 4/36
  • 6. И добавляем фабрики public class Adapter { public void processMessage() { final Source source = SourceFactory.getSource(); final Converter converter = ConverterFactory.getConverter(); final Storage storage = StorageFactory.getStorage(); final Message inputMessage = source.getMessage(); final Message convertedMessage = converter.convert(inputMessage); storage.store(convertedMessage); } } 6/36
  • 7. Пишем тест @Test public void processMessage() throws Exception { SourceFactory.setSource(new MockSource("Hello from test!")); StorageFactory.setStorage(new MockStorage()); final Adapter adapter = new Adapter(); adapter.processMessage(); // assert that... } + Получилось написать тест − Статический (глобальный) контекст − Много бойлерплейта − Зависимости неочевидны 7/36
  • 8. Избавляемся от фабрик public class Adapter { private Source source; private Converter converter; private Storage storage; public void setSource(Source source) {…} public void setConverter(Converter converter) {…} public void setStorage(Storage storage) {…} public void processMessage() { final Message inputMessage = source.getMessage(); final Message convertedMessage = converter.convert(inputMessage); storage.store(convertedMessage); } } 8/36
  • 9. Переписываем тест @Test public void processMessage() throws Exception { final Adapter adapter = new Adapter(); adapter.setSource(new MockSource("Hello from test!")); adapter.setConverter(new SimpleConverter()); adapter.setStorage(new MockStorage()); adapter.processMessage(); // assert that... } + Получилось: Setter based Dependency Injection by Hand 9/36
  • 10. Последний штрих public class Adapter { private final Source source; private final Converter converter; private final Storage storage; public Adapter(Source source, Converter converter, Storage storage) { this.source = source; this.converter = converter; this.storage = storage; } public void processMessage() {…} } 10/36
  • 11. Dependency Injection (DI)  Паттерн проектирования (design pattern)  О компонентах и их зависимостях  Позволяет отделить объявление зависимости от разрешения зависимости (и в пространстве, и во времени)  Является частью более общего принципа Inversion of Control (Hollywood principle – «Don't call us, we'll call you».) 11/36
  • 12. Причем тут тесты?  Тесты не самоцель, но…  С одной стороны, практически, DI позволяет проще писать тестопригодный код  А с другой стороны, концептуально, тесторигодность кода является индикатором хорошей слабосвязанной архитектуры (loose coupling)  В конечном итоге DI помогает удобнее писать слабосвязный код 12/36
  • 13. Можно было пойти другим путем public class Adapter { public void processMessage() { final Source source = UniversalFactory.get("source", Source.class); final Converter converter = UniversalFactory.get("converter", Converter.class); final Storage storage = UniversalFactory.get("storage", Storage.class); final Message inputMessage = source.getMessage(); final Message convertedMessage = converter.convert(inputMessage); storage.store(convertedMessage); } } + Получилось: Service Locator 13/36
  • 14. Паттерны DI и SL часто противопоставляются DI зависимости определяет статически  Проще разобраться в связях  Компилятор многое может проверить и подсказать  Но иногда это является ограничением SL – динамически  Взаимосвязи запутаны, проще ошибиться  Но иногда без этого не обойтись 14/36
  • 15. IoC-контейнер Автоматизирует DI  Разрешает граф зависимостей  Конструирует компоненты по метаописанию зависимостей И привносит еще много полезностей  Управление жизненным циклом  Управление конфигурацией  AOP  … 15/36
  • 16. Disclaimer Автор не в коем случае не имеет цели принизить один фреймворк за счет другого 16/36
  • 18. Описываем зависимости <?xml version="1.0" encoding="UTF-8"?> <beans …> <bean id="adapter" class="custis.seminars.diinjava.spring.Adapter" > <property name="source" ref="source"/> <property name="converter" ref="converter"/> <property name="storage" ref="storage"/> </bean> <bean id="source" class="custis.seminars.diinjava.spring.FileSource" /> <bean id="converter" class="custis.seminars.diinjava.spring.SimpleConverter" /> <bean id="storage" class="custis.seminars.diinjava.spring.DatabaseStorage" /> </beans> * Похоже на императив, но это декларатив 18/36
  • 19. Запускаем контейнер final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml"); adapter = applicationContext.getBean("adapter", Adapter.class); + Код адаптера не изменился + …нет зависимости от Spring’а + …не надо его писать в каком-либо специальном стиле 19/36
  • 21. Lifecycle Management  singleton – создается один экземпляр  prototype – создается отдельный экземпляр при каждом обращении <bean id="adapter" class="custis.seminars.diinjava.autowiring.Adapter" autowire="byType" scope="singleton" init-method="init" destroy-method="close" /> […] applicationContext.destroy(); 21/36
  • 22. Метаданные в компоненте @Scope(SCOPE_SINGLETON) public class Adapter { private Source source; private Converter converter; private Storage storage; @Autowired public void setSource(Source source) {…} @Autowired public void setConverter(Converter converter) {…} @Autowired(required = false) public void setStorage(Storage storage) {…} @PostConstruct public void init() {…} @PreDestroy public void close() {…} } 22/36
  • 23. Выбор между несколькими реализациями 23/36 <bean id="source" class="custis.seminars.diinjava.autowiring.FileSource" /> @Autowired @Qualifier("source") public void setSource(Source source) {…} − Легко ошибиться, и проявится это только в рантайме
  • 25. Pure Java config public class AdapterModule extends AbstractModule { @Override protected void configure() { bind(SimpleConverter.class); bind(Source.class).to(FileSource.class); bind(Storage.class).toInstance(new DatabaseStorage()); } } final Injector injector = Guice.createInjector(new AdapterModule()); adapter = injector.getInstance(Adapter.class); 25/36
  • 26. Annotation based @Singleton public class Adapter { private final Source source; private final Converter converter; private final Storage storage; @Inject public Adapter(Source source, Converter converter, Storage storage) { this.source = source; this.converter = converter; this.storage = storage; } public void processMessage() {…} } * Зависимость от аннотаций, но они стандартные 26/36
  • 27. Pure Java config public class AdapterModule extends AbstractModule { @Override protected void configure() {…} @Provides Source fileSource() { return new FileSource(); } } * В Spring 3.0 появился JavaConfig 27/36
  • 28. Provider interface public interface Provider <T> { T get(); } bind(Validator.class).to(SimpleValidator.class); public class Adapter { private Provider<Validator> validator; @Inject public void setValidator(Provider<Validator> validator) {…} public void processMessage() { ... validator.get().validate(inputMessage); ... } } 28/36
  • 29. Provider interface Когда нужно…  отложить создание (тяжелое, условное)  много экземпляров (the new «new»)  вложить более узкий скоуп в широкий 29/36
  • 30. Выбор между несколькими реализациями 30/36 @BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) public @interface FileBased {} @Inject public Adapter(@FileBased Source source, Converter converter, Storage storage) {…} bind(Source.class).annotatedWith(FileBased.class).to(FileSource.class); + Typesafe – компилятор проверит
  • 31. CDI/Weld JSR 299: Contexts and Dependency Injection for the Java EE platform Weld – reference implementation for JSR-299 31/36
  • 32. CDI  Конфигурация похожа на Guice  Нет DSL — используется @Produce и сканирование classpath  Стандартизирует @Inject, @Sengleton, Provider<T> и т. д.  Тесно интегрируется с EJB-контейнером 32/36
  • 33. Instance – Provider на стероидах  Расширяет возможности Provider Instance<T> extends Provider<T>  …опциональные зависимости if (instance.isUnsatisfied()) {…}  …многозначные зависимости if (instance.isAmbiguous()) { for (T t : instance) {...} }  …динамическое разрешение зависимостей (SL) adapter = instance.select(Adapter.class).get(); 33/36
  • 34. Event<T> public class Adapter { @Inject Event<AdapterStarted> adapterStartedEvent; @PostConstruct public void init() { adapterStartedEvent.fire(new AdapterStarted()); } } public class AnyOtherManagedBean{ public void onAdapterStart( @Observes AdapterStarted adapterStarted) {…} } 34/36
  • 35. О чем не рассказал  AOP и method intercepting  Генерализованные типы зависимостей  Многозначные зависимости  Scopes  … 35/36