我认为我的问题是基于体系结构的,但不是很确定,因此我将尝试解释其现实情况。
我正在使用的软件是面向整体的,但与SOAP完全兼容。架构如下:
通过Web服务进行调用时,Servlet将调用该工厂并执行相同的逻辑,就像来自Web项目(Maven)的调用直接调用工厂一样。
换句话说:
/**
* The main interface defining what a transaction is.
*/
public interface ITransaction <Q extends GenericRequest, P extends GenericResponse> {
P businessLogic(Q req);
void executeControls(String transactionId, Q params, PerimetreAppel environnement)
default void controleLicence() throws NassurCoreException
{
//TODO : contrôles de la licence à effectuer.
}
/**
* Log before transaction
*/
default void logEntree() throws NassurCoreException
{
//TODO to be implemented
}
/**
* Log after transaction
*/
default void logSortie() throws NassurCoreException
{
//TODO to be implemented
}
/**
* Checks that the user can call transaction
*/
default void controleDroits() throws NassurCoreException
{
//TODO to be implemented
}
//...
//Some other method not necessarily implemented in each transaction
}
/**
* The abstract defining the default behaviour of a transaction
*/
public abstract class AbstractTransaction<Q extends GenericRequest, P extends GenericResponse> implements ITransaction<Q, P>{
@Autowired
private ControlService controlService;
//.... some other autowired fields
@Autowired
protected UserDetailsService userDetailsService;
protected String idTransaction;
//Every transaction must implement its own logic
P businessLogic(Q params);
@Override
public void initialisation(String trId)
{
this.idTransaction = trId;
}
@Override
@Transactional
public void executeControls(String transactionId, Q params, PerimetreAppel environnement)
{
//Some controls found from database, and executed
// A control consists of a combination between java checks and some Jruby executed from the Service
List<SomeEntity> list = someEntityRepository.findByTransactionId(transactionId);
for(SomeEntity e : list){
controlService.executeUnitControl(e, params);
}
}
}
//Example Transaction
public class PersonViewTransaction extends AbstractTransaction<PersonViewRequest, PersonViewResponse>{
@Override
@Transactional
public PersonViewResponse businessLogic(PersonViewRequest req){
//...
}
}
//Example Transaction
public class PersonEditTransaction extends AbstractTransaction<PersonEditRequest, PersonEditResponse> {
@Override
@Transactional
public PersonEditResponse businessLogic(PersonEditRequest req){
//...
}
}
//Example Transaction
public class PersonSearchTransaction extends AbstractTransaction<PersonSearchRequest, PersonSearchResponse> {
@Override
@Transactional
public PersonSearchResponse businessLogic(PersonSearchRequest req){
//...
}
}
那些Bean在application-context.xml中声明。
public class TransactionFactory
{
public static GenericResponse executeTransaction(String id, GenericRequest req, HttpServletRequest request)
throws SomeExceptions
{
ServletContext servletCtx = request.getSession().getServletContext();
ApplicationContext actualCtx = WebApplicationContextUtils.getWebApplicationContext(servletCtx);
ITransaction tr = (ITransaction<GenericRequest, GenericResponse>) actualCtx.getBean(id.name());
if (tr == null)
{
throw new Exception("internal Error", null);
}
return executeStack(id, tr, req, request);
}
private static GenericResponse executeStack(String id, ITransaction tr, GenericRequest req, HttpServletRequest request)
throws SomeExceptions
{
try
{
tr.initialisation(id);
tr.controleLicence();
tr.logEntree();
tr.controleDroits();
//...Several operations calling ITransaction
tr.executeControls(id, req, provenance);
//Calling transaction logic
GenericResponse resp = tr.businessLogic(req);
//...Many "after-business" other calls
return resp;
}
catch (SomeExceptions e)
{
logger.error(e);
throw e;
}
}
}
有些神秘,当在同一个transactionId上同时进行两个调用时,executeControls
会抛出一些奇怪的返回值,好像两个执行都混在同一个bean中(对我来说,这似乎是线程安全的,但不是这样)确定...):
List<SomeEntity> list = someEntityRepository.findByTransactionId(transactionId);
for(SomeEntity e : list){
controlService.executeUnitControl(e, params);
}
executeUnitControl
检查控件是否必须应用,并在需要时引发错误。更详细地说,这是基于一个以参数为参数的JRuby脚本,以构建可配置的和非基于Java的业务逻辑。
非常感谢您的帮助,如果有法国人,我随时愿意与他们聊天,以解释更多详细信息!