- Fabrice Bibonne : support aux développeurs sur les technologies java
- Insee :
- Produit, analyse et diffuse des informations sur l’économie et la société françaises
- Diffuse également des métadonnées comme les référentiels géographiques à travers des API
- POC de la refonte de Metadata API avec approche contract first :
- la spec OAS est une spécification
- Eviter une génération laborieuse "du swagger"
- Documentation fidèle au besoin, au code
- Implémentation contrainte as code
- Fonctionnement d'un controlleur (générique) :
- Appeler la bonne requête Sparql
- Convertir le résultat dans la bonne entité
- La retourner
Extensions OpenApi Generator- Générer l'implémentation au runtime (comme Spring Data)
- Avec
MethodReplacer
?- Définition xml seulement
- Peu utilisé
- Pas compatible avec un contrôle d'accès (
@PreAuthorize
)
- Autre chose ?
- Programmation orientée Aspect
- Paradigme de programmation
- On s'intéresse aux aspects transverses de l'application (transactions)
- La gestion des aspects est centralisée
- On court-circuite les traitements métier pour y insérer les traitements relatifs aux aspects
-
cglib (code generation library) repackagé par Spring
code
schéma
public void onApplicationEvent(@NonNull ApplicationContextInitializedEvent event) {
/* ... */
new ClassPathScanningCandidateComponentProvider(false){...}.findCandidateComponents(interfaceControllerPackage);
/* ... */
controllerMetadatas.forEach( classMetadata -> {
/* ... */
genericApplicationContext.registerBeanDefinition(advisorName,
getPointcutBeanDefinition(namesOfMethodsToIntercept));
genericApplicationContext.registerBean(
classMetadata.getClassName(), ControllerProxyFactoryBean.class,
controllerInterface, advisorName);
/* ..*/
});
/* ... */
}
public class ControllerProxyFactoryBean extends ProxyFactoryBean {
public ControllerProxyFactoryBean(Class<?> controllerClass, String advisorName) {
setSingleton(true);
setInterfaces(controllerClass);
setInterceptorNames(advisorName);
}
}
public Optional<?> process(@NonNull Method method, @NonNull Object[] arguments)
throws ArgumentException{
String methodName=method.getName();
Optional<QueryTemplate> queryTemplate= queryTemplateSupplier.get(methodName);
if (queryTemplate.isEmpty()) {
throw new UnsupportedOperationException(STR."Method \{methodName} not supported");
}
String query = queryTemplate.get().format(arguments);
return ofNullable(unmarshaller.unmarshal(queryExecutor.execute(query), method));
}
public Optional<QueryTemplate> get(@NonNull String methodName) {
return Optional.ofNullable(switch (methodName) {
case "getcogcom" -> queryTemplate().withFindByCode()
.codeAtPosition(0).dateAtPosition(1)
.forTerritory("Commune");
case "getcogdep" -> queryTemplate().withFindByCode()
.codeAtPosition(0).dateAtPosition(1)
.forTerritory("Departement");
case "getTerritoireByTypeAndCode" -> queryTemplate().withFindByCode()
.codeAtPosition(0).dateAtPosition(2)
.forUnknownTerritoryType(1);
/* ... */
default -> null;
});
}
- Pistes d'amélioration pour le POC
- simplifier la déclaration des pointcuts
- Utiliser la réflexion pour associer endpoints et requêtes SPARQL
- Etre indépendant de Spring Boot
- Spring AOP :
- Outil puissant pour gérer des aspects transverses ou génériques dans une application Spring
- Très bien intégré avec l'écosystème Spring
- Plutôt pour les implémentations internes de Spring mais bon à connaître
QR code
MERCI !
flowchart LR
subgraph Code
I1[Intruction 1]
I2[Intruction 2]
subgraph AOP Proxy
extra[extra behavior]
method[instruction 3 : Method call]
end
I4[Intruction 4]
I5[...]
end
subgraph Aspect
Advice
Pointcut["Pointcut : 'call()'"]
end
Pointcut--"Join Point"--> method
Advice--"woven aspect"-->extra
Aspect --"Weaving"--> Code