Мы продолжаем наш урок об интеграции Spring 3 , Hibernate , JPA и JBoss 4.2.x — 4.3 .
Последний шаг — создание службы Spring для предоставления функциональности конечному пользователю. Мы должны создать интерфейсный класс и соответствующий класс реализации. Сначала интерфейс класса:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
package com.mycomp.myproject.services;import com.mycomp.myproject.dto.EmployeeDTO;public interface ExampleService { public EmployeeDTO findEmployee(long employeeId); public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception; public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception; public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception; public void deleteEmployee(long employeeId) throws Exception; } |
Как видите, это классический интерфейсный класс Java. Мы собираемся реализовать функции Create, Retrieve, Update, Delete (CRUD) для объекта EmployeeDTO.
Ниже приведен класс реализации указанного интерфейса.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
package com.mycomp.myproject.services.impl;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.mycomp.myproject.dao.EmployeeDAO;import com.mycomp.myproject.dto.EmployeeDTO;import com.mycomp.myproject.services.ExampleService;@Service("exampleService")public class ExampleServiceImpl implements ExampleService { @Autowired private EmployeeDAO employeeDAO; @PostConstruct public void init() throws Exception { } @PreDestroy public void destroy() { } public EmployeeDTO findEmployee(long employeeId) { return employeeDAO.findById(employeeId); } @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); if(employeeDTO == null) { employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription); employeeDAO.persist(employeeDTO); } } @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); if(employeeDTO != null) { employeeDTO.setEmployeeName(name); employeeDTO.setEmployeeSurname(surname); employeeDTO.setJob(jobDescription); } } @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void deleteEmployee(long employeeId) throws Exception { EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); if(employeeDTO != null) employeeDAO.remove(employeeDTO); } @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { EmployeeDTO employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription); employeeDAO.merge(employeeDTO); }} |
Что следует отметить здесь:
- Мы используем аннотацию стереотипа @Service («exampleService»), чтобы объявить, что этот класс представляет службу Spring с именем «exampleService». Контейнер Spring будет запускать все службы при запуске.
- Мы используем аннотацию @Autowire, чтобы внедрить экземпляр класса DAO в «exampleService». Для правильного создания экземпляра службы контейнер Spring должен сначала разрешить все потенциальные ссылки между службами, поэтому он создает экземпляр класса DAO и вставляет экземпляр в соответствующее поле «exampleService» — поле employeeDAO. В случае, если вам интересно, внедрение зависимости выполняется в соответствии с типом (Class) и, если не выполняется в соответствии с именем, это означает, что если мы определили несколько служб одного и того же типа (Class), то внедренная будет одна с тем же именем как обозначенное поле.
- Мы используем аннотации Java @PostConstruct и @PreDestroy, чтобы объявить методы, которые будут вызываться контейнером Spring после инициализации (все инъекции зависимостей выполняются) и предварительного уничтожения службы.
- Мы используем аннотацию @Transactional для всех методов, которым необходимо выполнить операцию обновления базы данных (INSERT, UPDATE, DELETE).
- Мы НЕ используем аннотацию @Transactional для методов, которые выполняют операции извлечения (FIND) над базой данных (за исключением объектов, которые содержат лениво инициализированные ссылки — см. Ниже), и / или не выполняют никаких операций с базой данных. Это связано с тем, что каждый раз, когда вы вызываете метод, аннотированный как транзакционный, контейнер Spring включает в себя диспетчер сущностей вызова JPA и, как следствие, диспетчер транзакций платформы, чтобы определить поведение транзакции, которое будет применяться, вводя заметное снижение производительности, особенно для приложений с низкой задержкой / высокой пропускной способностью.
- Для методов, которые выполняют операции извлечения (FIND) для объектов, которые содержат лениво инициализированные ссылки, вы должны использовать аннотацию @Transactional , обозначая тип распространения «NESTED », чтобы Spring мог поддерживать сеанс Hibernate открытым для всего вызова метода
- Транзакционное поведение применяется только при обращениях клиентов к сервису. Транзакционное поведение не применяется к внутриоперационным вызовам. Например, если клиент вызывает операцию, которая не аннотирована как транзакционная, и реализация последней вводит вызов другой операции того же сервиса, которая аннотирована транзакционной, тогда для объединенных операций транзакционное поведение не будет применяться.
- Конечный пользователь должен всегда получать доступ к услуге через определенный интерфейс
Это был действительно большой урок!
Надеюсь, вам понравилось.
Джастин