3.4.1.1. 创建服务
服务接口的名称应以 Service
结尾,实现类的名称应以 ServiceBean
结尾。
CUBA Studio 能帮助轻松创建服务接口的脚手架代码和存根类。Studio 还会自动在 spring.xml
中注册新服务。要创建服务,请使用 CUBA 项目树的 Middleware 节点中的 New>Service 任务。
如果要手动创建服务,请按照以下步骤操作。
在 global 模块中创建服务接口(因为服务接口必须在所有层中可用),并在其中指定服务名称。建议使用以下格式指定名称:
{project_name}_{interface_name}
。例如:package com.sample.sales.core;
import com.sample.sales.entity.Order;
public interface OrderService {
String NAME = "sales_OrderService";
void calculateTotals(Order order);
}
在 core 模块中创建服务类,并使用接口中指定的名称向其添加
@org.springframework.stereotype.Service
注解:package com.sample.sales.core;
import com.sample.sales.entity.Order;
import org.springframework.stereotype.Service;
@Service(OrderService.NAME)
public class OrderServiceBean implements OrderService {
@Override
public void calculateTotals(Order order) {
}
}
作为托管 bean 的服务类应放在包的树结构中,其根目录需要在spring.xml文件的 context:component-scan
元素中指定。这时,spring.xml
文件会包含以下元素:
<context:component-scan base-package="com.sample.sales"/>
这意味着将从 com.sample.sales
包开始搜索此应用程序 block 中带注解的 bean。
如果不同的服务或其它中间件组件需要调用相同的业务逻辑,则应将其提取并封装在适当的托管 Bean中。例如:
// service interface
public interface SalesService {
String NAME = "sample_SalesService";
BigDecimal calculateSales(UUID customerId);
}
// service implementation
@Service(SalesService.NAME)
public class SalesServiceBean implements SalesService {
@Inject
private SalesCalculator salesCalculator;
@Transactional
@Override
public BigDecimal calculateSales(UUID customerId) {
return salesCalculator.calculateSales(customerId);
}
}
// managed bean encapsulating business logic
@Component
public class SalesCalculator {
@Inject
private Persistence persistence;
public BigDecimal calculateSales(UUID customerId) {
Query query = persistence.getEntityManager().createQuery(
"select sum(o.amount) from sample$Order o where o.customer.id = :customerId");
query.setParameter("customerId", customerId);
return (BigDecimal) query.getFirstResult();
}
}