SPRING-SOURCE.RU | |
|
|
Обсудим следующий сегмент кода:
Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("jdbc/WroxJDBCDS”); Connection conn = ds.getConnection("user”, "pass”); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM Cust” ); while( rs.next() ) System.out.println( rs.getString(1)) ; rs.close() ; stmt.close() ; conn.close() ; con.close();
Этот код получает JDBC (Java Database Connectivity) DataSource из контейнера используя JNDI (Java Naming and Directory Interface). В J2EE это нужно для получения JDBC соединения. Если разбирать по шагам, то компонент получает DataSource через следующие шаги:
Обсудим следующий код из Spring компонента:
private DataSource ds; public void setDs(DataSource datasource) { ds = datasource; } ... Connection conn = ds.getConnection("user”, "pass”); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM Cust” ); while( rs.next() ) System.out.println( rs.getString(1)) ; rs.close() ; stmt.close(); conn.close();
Этот код делает тоже самое, что и предыдущий сегмент кода. Тем не менее, фактически компонент обращался к контейнеру за DataSource. Сейчас, код просто использует private переменную ds, не зная какой именно DataSource будет в нее записан.
DataSource создается не внутри компонента. Здесь, наоборот компонент получает нужный DataSource через setDs метод. Все это и есть инверсия контроля. Контроль над используемыми ресурсами инвертирован, контроль перешел от компонента к контейнеру и его конфигурации. В этом случае, Spring контейнер принимает решение вместо компонента.
Конечно, в Spring, DataSource может быть связан во время старта посредством редактирования beans.xml файла.
<bean name="wroxBean" class="com.wrox.beginspring.DataBean"> <property name="ds" ref="jdbcds" /> </bean>
Компонент на левой стороне – это стандартный не IoC компонент, и он обращается к контейнеру за двумя ресурсами (beans). На правой стороне контейнер создает необходимые ресурсы и затем делает инъекцию внутрь компонента, эффективно инвертируя контроль над выбранными ресурсами от компонента к контейнеру.
В предыдущем коде инъекция делается в компонент через setDs метод, эта техника получила название как инъекция зависимости. Фактически, использование setter метода, для инъекции DataSource, называется как setter инъекция. Spring также поддерживает constructor инъекцию, где зависимый ресурс вводится через конструктор.
Чтобы увидеть инъекцию зависимости в действии вам не нужно перекомпилировать свой проект, так как бины связаны через файл описания контекста.
Результат должен быть таким: The result of 3000 plus 3 is 3003!
<?xml version=”1.0” encoding=”UTF-8”?> <beans xmlns=”http://www.springframework.org/schema/beans” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”> <bean id=”screen” class=”com.wrox.begspring.ScreenWriter” /> <bean id=”multiply” class=”com.wrox.begspring.OpMultiply” /> <bean id=”add” class=”com.wrox.begspring.OpAdd” /> <bean id=”opsbean” class=”com.wrox.begspring.CalculateSpring”> <property name=”ops” ref=”multiply” /> <property name=”writer” ref=”screen”/> </bean> </beans>
Результат будет следующим: The result of 3000 times 3 is 9000!
Поведение приложения было изменено и различные компоненты вводятся через setter метод, без какой-либо перекомпиляции.
Код компонента CalculateSpring имеет setter метод для ops свойства, это дает возможность контейнеру Spring IoC делать инъекцию в компонент во время выполнения. Следующий код показывает setter метод:
package com.wrox.begspring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class CalculateSpring { private Operation ops; private ResultWriter wtr; public void setOps(Operation ops) { this.ops = ops; } public void setWriter(ResultWriter writer) { wtr = writer; }
Когда CalculateSpring бин соединен в beans.xml, setter инъекция зависимости используется для связывания реализации OpMultiply, вместо бывшего OpAdd, с ops свойством. Эта setter инъекция выделена в следующем коде:
<bean id=”opsbean” class=”com.wrox.begspring.CalculateSpring”> <property name=”ops” ref="multiply" /> <property name="writer" ref="screen"/> </bean>
Как вы могли увидеть, инъекция зависимостей дает возможность JavaBean компонентам изменять связи без компиляции в IoC контейнере.
Copyright © 2024 |