Шаблоны Dependeny Injection и Inversion of control в Srping
- Инверсия управления (IoC)
- Внедрение зависимостей (DI)
- Пример использования
Содержание
Инверсия управления (IoC) и внедрение зависимостей (DI) — два важных принципа Spring Framework, популярной платформы на основе Java для создания приложений корпоративного уровня.
IoC — это принцип проектирования, позволяющий передавать управление от объекта внешнему объекту. Это означает, что объект не контролирует свое собственное поведение, а полагается на внешние сущности для обеспечения своих зависимостей.
Внедрение зависимостей (DI) — это конкретная реализация принципа IoC, в которой внешний объект отвечает за предоставление объекта с его необходимыми зависимостями. В Spring эти зависимости можно указать в файлах конфигурации XML или аннотациях, и платформа автоматически предоставляет их при создании объекта.
Использование IoC и DI в Spring Framework имеет много преимуществ, включая улучшенную тестируемость, несвязанные компоненты и снижение накладных расходов на обслуживание. С DI объекты должны только указывать свои зависимости и не нужно их создавать и управлять ими, что делает объекты более гибкими и простыми для тестирования.
Вот пример того, как вы можете реализовать классы TextEditor и TextProcessor, используя принципы инверсии управления (IoC) и внедрения зависимостей (DI) в Spring Framework:
interface TextEditor {
void setTextProcessor(TextProcessor processor);
String processText(String text);
}
@Component
class SimpleTextEditor implements TextEditor {
private TextProcessor processor;
@Override
public void setTextProcessor(TextProcessor processor) {
this.processor = processor;
}
@Override
public String processText(String text) {
return processor.process(text);
}
}
interface TextProcessor {
String process(String input);
}
@Component
class LowerCaseProcessor implements TextProcessor {
@Override
public String process(String input) {
return input.toLowerCase();
}
}
@Component
class UpperCaseProcessor implements TextProcessor {
@Override
public String process(String input) {
return input.toUpperCase();
}
}
@Configuration
class AppConfig {
@Bean
public SimpleTextEditor simpleTextEditor() {
return new SimpleTextEditor();
}
@Bean
public LowerCaseProcessor lowerCaseProcessor() {
return new LowerCaseProcessor();
}
@Bean
public UpperCaseProcessor upperCaseProcessor() {
return new UpperCaseProcessor();
}
}
class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SimpleTextEditor diEditor = context.getBean(SimpleTextEditor.class);
diEditor.setTextProcessor(context.getBean(LowerCaseProcessor.class));
System.out.println(diEditor.processText("HELLO"));
diEditor.setTextProcessor(context.getBean(UpperCaseProcessor.class));
System.out.println(diEditor.processText("hello"));
}
}
В этом примере мы используем @Component
аннотацию, чтобы указать, что SimpleTextEditor
, LowerCaseProcessor
и UpperCaseProcessor
являются управляемыми компонентами Spring. Затем мы используем @Configuration
аннотацию AppConfig
класса, чтобы указать, что он содержит определения Bean. Определения Bean создаются с использованием @Bean
аннотации к методам, которые возвращают желаемый экземпляр Bean.
Класс Main
использует Spring ApplicationContext
для получения экземпляров SimpleTextEditor
, LowerCaseProcessor
и UpperCaseProcessor
. Обрабатывает ApplicationContext
создание и внедрение Bean-компонентов, освобождая клиентский код от ответственности за управление жизненным циклом и созданием сервисов.
В этом примере клиентский код указывает только свои зависимости и полагается на платформу Spring для обработки создания и внедрения этих зависимостей. Это отделяет клиентский код от служб, упрощает его обслуживание и тестирование, а также позволяет создать более гибкую и динамичную систему.