В этой статье мы рассмотрим, как Spring влияет на уровень доступа к данным приложения. Наше обсуждение начинается с шаблона объекта доступа к данным (DAO). Этот шаблон, популярный в мире Java, обеспечивает более управляемый и более обслуживаемый уровень доступа к данным. Затем мы обсудим, как Spring влияет на классы приложений DAO при интеграции с Hibernate.
Spring является универсальной средой, которая играет разные роли во многих областях архитектуры приложений. Одна из этих областей — настойчивость. Spring не обеспечивает свою собственную структуру постоянства. Вместо этого он обеспечивает уровень абстракции над JDBC и различные платформы отображения O / R, такие как iBATIS SQL Maps, Hibernate, JDO, Apache OJB и Oracle TopLink. Эта абстракция обеспечивает согласованную управляемую реализацию доступа к данным.
Уровень абстракции Spring абстрагирует приложение от фабрики соединений, API транзакций и иерархий исключений, используемых базовой технологией персистентности. Код приложения всегда использует Spring API для работы с фабриками соединений, использует стратегии Spring для управления транзакциями и использует общую иерархию исключений Spring для обработки базовых исключений. Spring находится между классами приложения и инструментом отображения O / R, выполняет транзакции и управляет объектами соединения. Он переводит базовые исключения персистентности, выдаваемые Hibernate, в значимые, непроверенные исключения типа DataAccessException, Кроме того, Spring предоставляет IoC и AOP, которые можно использовать на уровне персистентности. Spring осуществляет транзакции Hibernate и предоставляет более мощный и всеобъемлющий подход к управлению транзакциями.
Шаблон объекта доступа к данным
Хотя вы можете получить объект Session и подключиться к Hibernate в любом месте приложения, рекомендуется, чтобы все взаимодействия с Hibernate осуществлялись только через отдельные классы. В связи с этим существует шаблон проектирования JEE, который называется шаблоном DAO. Согласно шаблону DAO все постоянные операции должны выполняться через специальные классы, технически называемые классами DAO . Эти классы используются исключительно для связи с уровнем данных. Целью этого шаблона является отделение кода, связанного с постоянством, от бизнес-логики приложения, что делает код более управляемым и обслуживаемым, позволяя гибко изменять стратегию постоянства без изменения бизнес-правил или логики рабочего процесса.
Шаблон DAO утверждает, что мы должны определить интерфейс DAO, соответствующий каждому классу DAO. Этот интерфейс DAO описывает структуру класса DAO, определяет все постоянные операции, которые необходимы бизнес-уровню, и (в приложениях на основе Spring) позволяет применять IoC для отделения бизнес-уровня от класса DAO.
План фасада обслуживания
При реализации уровня доступа к данным всегда используется шаблон Service Facade в дополнение к шаблону DAO. Этот шаблон указывает на использование промежуточного объекта, называемого сервисным объектом, между всеми объектами бизнес-уровня и объектами DAO. Служебный объект собирает методы DAO для управления как единицу работы. Обратите внимание, что только один класс обслуживания создается для всех DAO, которые реализуются в каждом случае использования.
Класс обслуживания использует экземпляры интерфейсов DAO для взаимодействия с ними. Эти экземпляры создаются из конкретных классов DAO контейнером IoC во время выполнения. Следовательно, объект службы не знает фактических деталей реализации DAO.
Независимо от стратегии персистентности, используемой вашим приложением (даже если оно использует прямой JDBC), настоятельно рекомендуется применять шаблоны DAO и Service Facade для разделения уровней приложений.
Реализация уровня данных с Hibernate
Давайте теперь посмотрим, как обсуждаемые шаблоны применяются к приложению, которое напрямую использует Hibernate. Следующий код показывает пример интерфейса DAO:
package com.packtpub.springhibernate.ch13;import java.util.Collection;public interface StudentDao { public Student getStudent(long id); public Collection getAllStudents(); public Collection getGraduatedStudents(); public Collection findStudents(String lastName); public void saveStudent(Student std); public void removeStudent(Student std);}
Следующий код показывает класс DAO, который реализует этот интерфейс DAO:
package com.packtpub.springhibernate.ch13;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.HibernateException;import org.hibernate.Query;import java.util.Collection;public class HibernateStudentDao implements StudentDao { SessionFactory sessionFactory; public Student getStudent(long id) { Student student = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); student = (Student) session.get(Student.class, new Long(id)); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return student; } public Collection getAllStudents(){ Collection allStudents = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std order by std.lastName, std.firstName"); allStudents = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return allStudents; } public Collection getGraduatedStudents(){ Collection graduatedStudents = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std where std.status=1"); graduatedStudents = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return graduatedStudents; } public Collection findStudents(String lastName) { Collection students = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std where std.lastName like ?"); query.setString(1, lastName + "%"); students = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return students; } public void saveStudent(Student std) { Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.saveOrUpdate(std); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } } public void removeStudent(Student std) { Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.delete(std); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }}
Как видите, все реализованные методы выполняют подпрограммы. Все сначала получают объект Session , получают объект Transaction , выполняют операцию сохранения, фиксируют транзакцию, откатывают транзакцию, если возникает исключение, и, наконец, закрывают объект Session . Каждый метод содержит много стандартного кода, который очень похож на другие методы.
Хотя применение шаблона DAO к постоянному коду приводит к более управляемому и обслуживаемому коду, классы DAO по-прежнему содержат много стандартного кода. Каждый метод DAO должен получить экземпляр Session , запустить транзакцию, выполнить операцию сохранения и зафиксировать транзакцию. Кроме того, каждый метод DAO должен включать свою собственную дублированную реализацию обработки исключений. Именно эти проблемы побуждают нас использовать Spring с Hibernate.
Шаблон шаблона. Чтобы очистить код и обеспечить более управляемый код, Spring использует шаблон под названием Шаблон шаблона . По этому шаблону объект шаблона оборачивает весь повторяющийся код. Затем этот объект делегирует постоянные вызовы как часть функциональности в шаблоне. В случае Hibernate HibernateTemplate извлекает весь шаблонный код, такой как получение сеанса, выполнение транзакции и обработка исключений.
Реализация уровня данных с помощью Spring
В Spring вам не нужно реализовывать код для получения объектов Session , запуска и фиксации транзакций и обработки исключений Hibernate. Вместо этого вы используете экземпляр HibernateTemplate для делегирования постоянных вызовов Hibernate без прямого взаимодействия с Hibernate.
Вот некоторые преимущества использования Spring в слое постоянства вместо прямого взаимодействия с Hibernate:
- В Spring объект HibernateTemplate взаимодействует с Hibernate. Этот объект удаляет шаблонный код из реализаций DAO.
- Любой вызов одного из методов HibernateTemplate генерирует общее исключение DataAccessException вместо HibernateException (специфичное для Hibernate исключение).
- Spring позволяет декларативно разграничивать транзакции, вместо реализации дублированного кода управления транзакциями.
Класс HibernateTemplate использует экземпляр SessionFactory для получения объектов Session для взаимодействия Hibernate. Интересно, что вы можете настроить объект SessionFactory через контейнер IoC Spring для создания экземпляров и внедрения в объекты DAO.
В следующих разделах обсуждается, как HibernateTemplate используется в классах DAO и как он настраивается с помощью SessionFactory в контейнере Spring IoC. Сначала давайте посмотрим на иерархию исключений Spring.
Весеннее исключение перевода
Spring предоставляет свою собственную иерархию исключений, которая находится в иерархиях исключений поддерживаемых инструментов отображения O / R. Он перехватывает любое исключение или ошибку базы данных, которая может быть выдана через JDBC или базовый инструмент отображения O / R, и преобразует перехваченное исключение в соответствующее исключение в своей собственной иерархии. Иерархия исключений Spring определяется как подкласс org.springframework.dao.DataAccessException . Spring перехватывает все исключения, возникающие в базовой технологии персистентности, и переносит их в экземпляр DataAccessException . Объект DataAccessException является непроверенным исключением, поскольку он расширяет RuntimeException, и вам не нужно его перехватывать, если вы этого не хотите.
Рефакторинг классов DAO для использования Spring
Spring предоставляет различные базовые классы DAO для различных технологий доступа к данным, которые он поддерживает. Например, Spring предоставляет HibernateDaoSupport для Hibernate, SqlMapClientDaoSupport для карт iBATIS SQL и JdoDaoSupport для JDO. Эти классы обертывают общие свойства и методы, которые требуются во всех подклассах реализации DAO.
Когда вы используете Hibernate с Spring, классы DAO расширяют класс Spring org.springframework.orm.hibernate3.support.HibernateDaoSupport . Этот класс оборачивает экземпляр org.springframework.orm.hibernate3.HibernateTemplate , который, в свою очередь, оборачивает экземпляр org.hibernate.SessionFactory . Как вы скоро увидите в этой статье, расширение класса HibernateDaoSupport позволяет согласованно настраивать все реализации DAO в виде bean-компонентов внутри контейнера IoC Spring. Их свойство SessionFactory настраивается и настраивается через контекст Spring.
В следующем коде показан простой интерфейс DAO для реализации DAO на основе Spring:
package com.packtpub.springhibernate.ch13;import java.util.Collection;public interface StudentDao { public Student getStudent(long id); public Collection getAllStudents(); public Collection getGraduatedStudents(); public Collection findStudents(String lastName); public void saveStudent(Student std); public void removeStudent(Student std);}
Здесь StudentDao — это интерфейс DAO с той же структурой, что и интерфейс, показанный в следующем коде.
HibernateException выдается за любой сбой при непосредственном взаимодействии с Hibernate. Когда используется Spring, HibernateException перехватывается Spring и преобразуется в DataAccessException для любого сбоя персистентности. Оба исключения не проверены, поэтому вам не нужно ловить их, если вы не хотите это делать.
В следующем коде показана реализация DAO для этого интерфейса DAO, который теперь использует Spring для взаимодействия с Hibernate:
package com.packtpub.springhibernate.ch13;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import java.util.Collection;public class HibernateStudentDao extends HibernateDaoSupport implements StudentDao { public Student getStudent(long id) { return (Student) getHibernateTemplate().get(Student.class, new Long(id)); } public Collection getAllStudents(){ return getHibernateTemplate(). find("from Student std order by std.lastName, std.firstName"); } public Collection getGraduatedStudents(){ return getHibernateTemplate().find("from Student std where std.status=1"); } public Collection findStudents(String lastName) { return getHibernateTemplate(). find("from Student std where std.lastName like ?", lastName + "%"); } public void saveStudent(Student std) { getHibernateTemplate().saveOrUpdate(std); } public void removeStudent(Student std) { getHibernateTemplate().delete(std); }}
Как видите, все постоянные методы в классе DAO используют метод getHibernateTemplate () для доступа к объекту HibernateTemplate . Как вы видели в предыдущем разделе, HibernateTemplate — это удобный класс Spring, который делегирует вызовы DAO API Hibernate Session. Этот класс предоставляет все методы Session Hibernate, а также множество других удобных методов, которые могут понадобиться классам DAO. Поскольку удобные методы HibernateTemplate не предоставляются интерфейсом Session, вы можете использовать find () и findByCriteria ()когда вы хотите выполнить HQL или создать объект Criteria. Кроме того, он оборачивает все лежащие в основе исключения, создаваемые методом Session, экземплярами непроверенной org.springframework.dao.DataAccessException .
Для удобства я рекомендую использовать класс HibernateDaoSupport в качестве базового класса для всех реализаций DAO Hibernate, но вы можете игнорировать этот класс и работать напрямую с экземпляром HibernateTemplate в классах DAO. Для этого определите свойство HibernateTemplate в классе DAO, которое инициализируется и настраивается через контейнер IoC Spring.
Следующий код показывает класс DAO, который теперь напрямую использует HibernateTemplate . Обратите внимание, что этот подход не рекомендуется, поскольку он вовлекает вас в объект HibernateTemplate как в классе DAO, так и в конфигурации DAO в контексте Spring:
package com.packtpub.springhibernate.ch13;import org.springframework.orm.hibernate3.HibernateTemplate;import java.util.Collection;public class HibernateStudentDao implements StudentDao { HibernateTemplate hibernateTemplate; public Student getStudent(long id) { return (Student) getHibernateTemplate().get(Student.class, new Long(id)); } public Collection getAllStudents(){ return getHibernateTemplate(). find("from Student std order by std.lastName, std.firstName"); } public Collection getGraduatedStudents(){ return getHibernateTemplate().find("from Student std where std.status=1"); } public Collection findStudents(String lastName) { return getHibernateTemplate(). find("from Student std where std.lastName like "+ lastName + "%"); } public void saveStudent(Student std) { getHibernateTemplate().saveOrUpdate(std); } public void removeStudent(Student std) { getHibernateTemplate().delete(std); } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; }}
Класс DAO теперь имеет метод setHibernateTemplate (), позволяющий Spring внедрить настроенный экземпляр HibernateTemplate в объект DAO.
Кроме того, класс DAO может отказаться от класса HibernateTemplate и напрямую использовать экземпляр SessionFactory для взаимодействия с Hibernate. В следующем коде показан HibernateStudentDao , который теперь работает непосредственно с объектом SessionFactory :
package com.packtpub.springhibernate.ch13;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.Query;import org.hibernate.SessionFactory;import org.springframework.orm.hibernate3.SessionFactoryUtils;import java.util.Collection;public class HibernateStudentDao implements StudentDao { SessionFactory sessionFactory; public Student getStudent(long id) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { return (Student) session.get(Student.class, new Long(id)); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection getAllStudents(){ Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery( "from Student std order by std.lastName, std.firstName"); Collection allStudents = query.list(); return allStudents; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection getGraduatedStudents(){ Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery("from Student std where std.status=1"); Collection graduatedStudents = query.list(); return graduatedStudents; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection findStudents(String lastName) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery( "from Student std where std.lastName like ?"); query.setString(1, lastName + "%"); Collection students = query.list(); return students; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void saveStudent(Student std) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { session.save(std); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void removeStudent(Student std) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { session.delete(std); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }}
Во всех описанных выше методах класс SessionFactoryUtils используется для получения объекта Session . Предоставленный объект Session затем используется для выполнения операции персистентности. SessionFactoryUtils также используется для преобразования HibernateException в DataAccessException в блоках catch и закрытия объектов Session в последних блоках. Обратите внимание, что эта реализация DAO обходит преимущества HibernateDaoSupport и HibernateTemplate . Вы должны управлять сессией Hibernate вручную (а также трансляцией исключений и управлением транзакциями) и реализовывать много стандартного кода.
org.springframework.orm.hibernate3.SessionFactoryUtils — это вспомогательный класс Spring для получения Session, повторного использования Session в транзакциях и преобразования HibernateException в универсальный DataAccessException .
Этот способ абсолютно не подходит для работы с Session in Spring. Всегда используйте класс HibernateTemplate для работы с объектами Session за кулисами. Однако в тех случаях, когда вам нужно работать непосредственно с объектами Session, вы можете использовать реализацию интерфейса org.springframework.orm.hibernate3.HibernateCallback в качестве обработчика для работы с Sessions. Следующий фрагмент кода показывает, как этот подход:
public void saveStudent(Student std) { HibernateCallback callback = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { return session.saveOrUpdate(std); } }; getHibernateTemplate().execute(callback); }
В этом коде создается неявная реализация HibernateCallback, и реализуется ее единственный метод doInHibernate () . Метод doInHibernate () принимает объект Session и возвращает результат операции персистентности, ноль, если нет. Затем объект HibernateCallback передается методу execute () HibernateTemplate для выполнения. Метод doInHibernate () просто предоставляет обработчик для работы непосредственно с объектами Session, которые получены и используются за кулисами.
Настройка Hibernate в контексте Spring
Spring предоставляет класс LocalSessionFactoryBean в качестве фабрики для объекта SessionFactory . Объект LocalSessionFactoryBean настраивается как bean-компонент внутри контейнера IoC с локальным источником данных JDBC или общим источником данных из JNDI.
Локальный JDBC DataSource может быть в свою очередь настроен как объект org.apache.commons.dbcp.BasicDataSource в контексте Spring:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>org.hsqldb.jdbcDriver</value> </property> <property name="url"> <value>jdbc:hsqldb:hsql://localhost/hiberdb</value> </property> <property name="username"> <value>sa</value> </property> <property name="password"> <value></value> </property></bean>
В этом случае org.apache.commons.dbcp.BasicDataSource (пул соединений с базой данных Jakarta Commons) должен находиться в пути к классу приложения.
Точно так же общий источник данных можно настроить как объект org.springframework.jndi.JndiObjectFactoryBean . Это рекомендуемый способ, который используется, когда пул соединений управляется сервером приложений. Вот способ настроить это:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/HiberDB</value> </property></bean>
Когда DataSource настроен, вы можете настроить экземпляр LocalSessionFactoryBean на настроенном DataSource следующим образом:
<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource"/> </property> ...</bean>
В качестве альтернативы вы можете настроить объект SessionFactory в качестве объекта ресурса на стороне сервера в контексте Spring. Этот объект связан как ресурс JNDI в среде JEE для совместного использования несколькими приложениями. В этом случае вам нужно использовать JndiObjectFactoryBean вместо LocalSessionFactoryBean :
<bean id="sessionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/hiberDBSessionFactory</value> </property></bean>
JndiObjectFactoryBean — это еще один фабричный компонент для поиска любого ресурса JNDI.
При использовании JndiObjectFactoryBean для получения предварительно сконфигурированной SessionFactory объекта, то SessionFactory объект уже должен быть зарегистрирован в качестве JNDI ресурса. Для этой цели вы можете запустить серверный класс, который создает объект SessionFactory и регистрирует его как ресурс JNDI.
LocalSessionFactoryBean использует три свойства: источник данных , mappingResources и hibernateProperties . Эти свойства следующие:
- источник данных относится к JDBC DataSource объекта , который уже определен как другой фасоли внутри контейнера.
- mappingResources указывает файлы отображения Hibernate, расположенные в пути к классам приложения.
- hibernateProperties определяет параметры конфигурации Hibernate.
У нас есть объект sessionFactory, настроенный следующим образом:
<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource"/> </property> <property name="mappingResources"> <list> <value>com/packtpub/springhibernate/ch13/Student.hbm.xml</value> <value>com/packtpub/springhibernate/ch13/Teacher.hbm.xml</value> <value>com/packtpub/springhibernate/ch13/Course.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.max_fetch_depth">2</prop> </props> </property></bean>
Свойство mappingResources загружает определения сопоставления в путь к классам. Вы можете использовать mappingJarLocations или mappingDirectoryLocations, чтобы загрузить их из файла JAR или из любого каталога файловой системы, соответственно.
По-прежнему можно настроить Hibernate с помощью hibernate.cfg.xml вместо настройки Hibernate, как показано ниже. Для этого настройте sessionFactory со свойством configLocation следующим образом:
<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource"/> </property> <property name="configLocation"> <value>/conf/hibernate.cfg.xml</value> </property></bean>
Обратите внимание, что hibernate.cfg.xml определяет определения отображения Hibernate в дополнение к другим свойствам Hibernate.
Когда объект SessionFactory настроен, вы можете настроить реализации DAO как компоненты в контексте Spring. Эти компоненты DAO — это объекты, которые ищутся из контейнера IoC Spring и используются бизнес-уровнем. Вот пример конфигурации DAO:
<bean id="studentDao" class="com.packtpub.springhibernate.ch13.HibernateStudentDao"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property></bean>
Это конфигурация DAO для класса DAO, который расширяет HibernateDaoSupport или напрямую использует свойство SessionFactory . Когда класс DAO имеет свойство HibernateTemplate , настройте экземпляр DAO следующим образом:
<bean id="studentDao" class="com.packtpub.springhibernate.ch13.HibernateStudentDao"> <property name="hibernateTemplate"> <bean class="org.springframework.orm.hibernate3.HibernateTemplate"> <constructor-arg> <ref local="sessionFactory"/> </constructor-arg> </bean> </property></bean>
В соответствии с предыдущим объявлением класс HibernateStudentDao имеет свойство hibernateTemplate , которое настраивается через контейнер IoC и инициализируется посредством внедрения конструктора и экземпляра SessionFactory в качестве аргумента конструктора.
Теперь любой клиент реализации DAO может найти контекст Spring, чтобы получить экземпляр DAO. В следующем коде показан простой класс, который создает контекст приложения Spring, а затем ищет объект DAO из контейнера Spring IoC:
package com.packtpub.springhibernate.ch13; public class DaoClient { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("com/packtpub/springhibernate/ch13/applicationContext.xml"); StudentDao stdDao = (StudentDao)ctx.getBean("studentDao"); Student std = new Student(); //set std properties //save std stdDao.saveStudent(std); }}