SlideShare una empresa de Scribd logo
1 de 29
Les dessous du
framework Spring
3 décembre 2015
Objectifs
 Exploiter certaines fonctionnalités méconnues de Spring
 Découvrir le fonctionnement interne du conteneur
 Eviter certains pièges
 Apprendre à partir d’exemples concrets issus d’applications métiers
Sommaire
 Post-processeurs et fabriques de beans Spring
 Intercepteur transactionnel et pièges de l’annotation @Transactional
 Lever des ambiguïtés lors de l’injection de beans
 Injection de beans de portées différentes
 Hiérarchie de contextes Spring
 Créer sa propre annotation
 Architecture pluggable
 Accès au contexte Spring
 Caractéristiques
o Appelé pendant le processus de création de tout bean Spring
o Implémente l’interface BeanPostProcessor
o 2 méthodes appelées avant et après la méthode d’initialisation du bean
o Peuvent être ordonnés
 Etapes de mise à disposition d’un bean
1. Création du bean par constructeur ou appel de méthode statique
2. Valorisation des propriétés du bean
3. Résolution des références vers d’autres beans (wiring)
4. Appel de la méthode postProcessBeforeInitialization() de chaque post-processor
5. Appel des méthodes d’initialisation du bean (@PostConstruct, afterPropertiesSet)
6. Appel de la méthode postProcessAfterInitialization() de chaque post-processor
7. Le bean est prêt à être utilisé par le conteneur
Les post-processeurs de bean (1/5)
Les post-processeurs de bean (2/5)
Chargement en
mémoire de la
définition des
beans
XML
Conf
Spring
Java
Classes
annotées
Instanciation du
bean ou appel de
la fabrique beans
 Etapes de mise à disposition des beans de portées singleton d’une application
Pour chaque
bean trouvé Appel des setters
Injection de beans
*
postProcess
BeforeInitialization
Pour chaque
BeanPost
Processor
*
Initalisation
Bean prêt
à l’emploi postProcess
AfterInitialization
afterPropertiesSet
@PostConstruct
*
Possibilités multiples :
1. modifier un bean
2. renvoyer un proxy
3. ajouer un intercepteur
 Usage des post-processeurs par Spring et des frameworks tiers
Les post-processeurs de bean (3/5)
Post-Processeur Description
AutowiredAnnotationBeanPostProcessor Active l’auto-wiring via les annotations @Autowired ou
@Inject
CommonAnnotationBeanPostProcessor Active la détection des annotations de la JSR-250
AsyncAnnotationBeanPostProcessor Active la détection de l’annotation @Async
ScheduledAnnotationBeanPostProcessor Active la détection de l’annotation @Scheduled
JmsListenerAnnotationBeanPostProcessor Active la détection de l’annotation @JmsListener
ApplicationContextAwareProcessor Permet de passer le contexte applicatif Spring aux beans
implémentant l’interface ApplicationContextAware
ScriptFactoryPostProcessor Permet d’accéder au résultat de scripts (Groovy, JRuby )
BusExtensionPostProcessor Active la détection automatique d’extension de bus CXF
JaxWsWebServicePublisherBeanPostProcessor Support CXF des annotations JAX-WS
CamelBeanPostProcessor Intégration de beans Spring dans Apache Camel
 Exemple d’utilisation
 Disposer d’une annotation @Alias se substituant à la syntaxe XML
 Demande d’évolution SPR-6736
 Définition d’un alias en XML :
 Equivalent en annotation :
Les post-processeurs de bean (4/5)
<bean id="movieController" class="MovieController"/>
<alias name="movieController" alias="filmController"/>
@Controller("movieController")
@Alias("filmController")
public class MovieController { }
 Mise en œuvre d’un AliasPostProcessor
Les post-processeurs de bean (5/5)
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface Alias {
String value();
}
public class AliasPostProcessor
implements BeanPostProcessor, BeanFactoryPostProcessor {
private ConfigurableListableBeanFactory configurableBeanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
Class<?> targetClass = AopUtils.getTargetClass(bean);
Annotation annotation = targetClass.getAnnotation(Alias.class);
if (annotation != null) {
configurableBeanFactory.registerAlias(beanName, ((Alias) annotation).value());
}
return bean;
}
 Lors du mécanisme d’injection, met un bean à disposition du conteneur
 Instancie ou réutilisation des beans (partage)
 Massivement utilisé par le conteneur Spring
 Exemple : HibernateSessionFactoryBean
 Implémente l’interface FactoryBean
 Ce n’est pas la fabrique qui est injectée mais le bean créé par la
fabrique (méthode getObject())
Fabrique de beans Spring (1/3)
 Exemple d’une fabrique fusionnant des listes de beans
 Input : plusieurs listes de beans Spring
 Output : une seule liste de beans Spring
 Utilisation avec la syntaxe XML :
Fabrique de beans Spring (2/3)
<bean id="annotatedClasses" class="ListMerger">
<property name="sourceLists">
<util:list>
<ref bean="customerAnnotatedClasses" />
<ref bean="aggreementAnnotatedClasses" />
</util:list>
</property>
</bean>
 Implémentation de la fabrique fusionnant des listes de beans
Fabrique de beans Spring (3/3)
public class ListMerger<V> implements FactoryBean<List<V>> {
private List<V> result = new ArrayList<V>();
@Override
public List<V> getObject() { return result; }
@Override
public boolean isSingleton() { return true; }
@Override
public Class<?> getObjectType() { return List.class; }
public void setSourceLists(List<List<V>> sourceLists) {
for (List<V> l : sourceLists) { this.result.addAll(l); }
}
}
Points de vigilance avec @Transactional (1/2)
 L’annotation @Transactional permet de délimiter des transactions
 Point 1 : Commit ou Rollback ?
@Transactional
public void addMovie(Movie movie) throws BusinessException {
movieDao.save(movie);
throw new BusinessException();
}
@Transactional
public void addMovie(Movie movie) throws BusinessException {
movieDao.save(movie);
throw new TechnicalException();
}
Par défaut, lorsqu’une checked exception est levée, Spring valide la transaction
Remédiation : utilisation du rollbackFor @Transactional(rollbackFor = Exception.class)
ou création d’une annotation dédiée @MyTransactional
Commit
Rollback
Points de vigilance avec @Transactional (2/2)
 Point 2: le film est-il sauvegardé dans une transaction ?
@Service
public class MovieService {
@Autowired IMovieDao movieDao;
public void addThenIndexMovie(Movie movie) {
addMovie(movie);
indexMovie(movie);
}
@Transactional
public void addMovie(Movie movie) { … }
private void indexMovie(Movie movie) { … }
}
@RequestMapping(value = "/movie/new")
public String create(@Valid Movie movie) {
movieService.addThenIndexMovie(movie);
return "redirect:/movie/" + movie.getId();
}
@RequestMapping(value = "/movie/new")
public String create(@Valid Movie movie) {
movieService.addMovie(movie);
return "redirect:/movie/" + movie.getId();
}
 Scénario 1 : appel direct à addMovie
 Scénario 2 : appel indirect à addMovie
Transactionnel
Non transactionnel
 Lors de l’injection de beans, Spring peut modifier la chaîne d’appel
 Design Pattern Proxy ou Intercepteur
 Exemples d’usage :
 Greffer des aspects
 Insérer un comportement transactionnel
 2 types de proxy en fonction de l’appelé :
 Interface par l’utilisation de proxy dynamique java.lang.reflect.Proxy
 Classe par instrumentation de code
Intercepteur transactionnel (1/2)
Intercepteur transactionnel (2/2)
MovieController JdkDynamicAopProxy TransactionInterceptor MovieService
addMovie
invoke
addMovie
Ouverture d’une
transaction car
addMovie annoté
addThenIndexMovie
addThenIndexMovie
addMovie
Pas de transaction car on ne
repasse pas par le proxy
Levée d’ambiguité avec @Primary (1/2)
 2 implémentations d’une même interface
@Service
public class NetflixService implements IMovieService { }
@Service
public class ImdbService implements IMovieService { }
 Spring est incapable de déterminer quel bean injecter
@Autowired
private IMovieService movieService;
NoUniqueBeanDefinitionException : expected single matching bean but found 2:
imdbService,netflixService
Levée d’ambiguité avec @Primary (2/2)
 Solution 1 : utilisation d’un qualifier
@Autowired
@Qualifier("netflixService")
private IMovieService movieService;
 Solution 2 : définition d’un bean principal (bean par défaut)
@Service
@Primary
public class NetflixService implements IMovieService { }
 Permet de ne pas alourdir l’injection de dépendance lorsque dans la plupart des cas c’est le bean
netflixService qui doit être injecté.
 Autres exemples : DataSourceTransactionManager vs JmsTransactionManager
NetflixService vs MockMovieService
 Comment injecter un bean de portée session dans un singleton ?
 Rappels
 Un bean de portée Singleton
 doit d’être thread-safe
 est créé au démarrage du conteneur
 Un bean de portée session est créé pour chaque session web utilisateur
 Cas d’usage
 Dans les contrôleurs, ne plus manipuler directement la session HTTP
 Toutes les données à mettre en session sont modélisées dans un ou plusieurs beans
 Avoir accès dans un service métier aux informations de l’utilisateur connecté
 Besoin : contrôle des habilitations, historisation, logs
 Un bean de portée requête peut remplacer l’utilisation du ThreadLocal
Injection de beans de portée différente (1/3)
 Solution
 Proxifier le bean de portée Session
 Le proxy est chargé d’aiguiller les appels vers le bean session approprié
 Illustration
Injection de beans de portée différente (2/3)
Service
singleton
Conteneur Spring
Proxy
Informations
Utilisateur
Contrôleur
singleton
James
session
John
session
getName() getName()
 Exemples de mise en oeuvre
Injection de beans de portée différente (3/3)
@Configuration
public class UserConfig {
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserDetails userDetails() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (UserDetails) authentication.getPrincipal();
}
}
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MovieModelView {
private Movie selectedMovie;
private String email;
…
}
 Les scopes request et session n’ont de sens que dans un conteneur web
 Erreur lorsqu’ils sont utilisés dans un simple ApplicationContext
 java.lang.IllegalStateException: No Scope registered for scope 'session’
Tests de beans de portée web
@WebAppConfiguration
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class TestWebScope {
 Solution 1 : l’annotation
@WebAppConfiguration
 Solution 2 : déclarer un bean
CustomScopeConfigurer et utiliser le scope
SimpleThreadScope
@Configuration
static class Config {
@Bean
public CustomScopeConfigurer customScopeConfigurer() {
CustomScopeConfigurer csc = new CustomScopeConfigurer();
Map<String, Object> map = new HashMap<String, Object>();
map.put("session", new SimpleThreadScope());
map.put("request", new SimpleThreadScope());
csc.setScopes(map);
return csc;
} }
 Une application Spring est composée d’un ou plusieurs contextes applicatifs
 Les contextes applicatifs Spring peuvent être hiérarchiques
 C’est typiquement le cas dans les applications web basées sur Spring MVC
Hiérarchie de contextes (1/4)
Root
WebApplicationContext
DAO
Services métiers
Child
WebApplicationContext
Contrôleurs IHM
Child
WebApplicationContext
Contrôleurs REST
 Les beans déclarés dans le contexte parent sont visibles des contextes
enfants
 Respect du découpage en couche
 Alternative aux multi-wars
 Chargement du contexte parent depuis un listener JEE déclaré dans le
web.xml :
Hiérarchie de contextes (2/4)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/business-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 Chargement des contextes enfants via les DispatcherServlet déclarés
dans le web.xml
Hiérarchie de contextes (3/4)
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web
.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web
.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:rest-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest</url-pattern>
</servlet-mapping>
 L’annotation @ContextHierarchy rend possible l’écriture de tests
d’intégration avec hiérarchie de contextes
Hiérarchie de contextes (4/4)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(name = "parent", locations = "classpath:business-config.xml"),
@ContextConfiguration(name = "child", locations = "classpath:spring-mvc-config.xml") })
public class SpringConfigTest {
@Autowired
private WebApplicationContext childContext;
@Test
public void parentChildContext) {
ApplicationContext parentContext = childContext.getParent();
assertTrue(parentContext.containsBean("myService"));
assertTrue(childContext.containsBean("myService"));
assertFalse(parentContext.containsBean("myController"));
assertTrue(childContext.containsBean("myController"));
}
}
 Possibilité d’étendre le jeu d’annotations @Component, @Service,
@Repository et @Controller
 Exemple d’annotation utilisée sur les classes de mapping objet-objet :
Créer sa propre annotation @Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Mapper {
String value() default "";
}
@Pointcut("within(@com.mycompagny.spring.Mapper *)")
public void mapper() { /**/ }
 Exemple d’utilisation en AOP dans les points de coupe :
 Spring permet d’injecter une collection de beans du même type
Architecture pluggable
@Service
public class PluginManager {
@Autowired
private List<IPlugin> pluginList;
@Autowired
private Map<String, IPlugin> pluginMap;
}
 Mécanisme d’extension très simple
 Exemple : ajout de nouveaux formats de fichiers dans un composant
d’upload de fichiers
 Depuis une Servlet
Accès au contexte Spring
public class MovieServlet extends HttpServlet {
private IMovieService movieService;
@Override
public void init() throws ServletException {
ApplicationContext applicationContext
= WebApplicationContextUtils.getWebApplicationContext(getServletContext());
movieService = applicationContext.getBean(IMovieService.class);
}
@Component
public class MonBean {
@Autowired
private ApplicationContext applicationContext;
 Depuis un bean Spring
public class MonBean implements
ApplicationContextAware {
@Override
public void setApplicationContext(
ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
Conclusion
 Les mécanismes utilisés en interne par Spring permettent
d’étendre les fonctionnalités du framework
 Connaître le fonctionnement des proxy et des
intercepteurs permet d’éviter des bugs
 Dans une application web, la portée des beans doit être
choisie judicieusement

Más contenido relacionado

La actualidad más candente

Formation JPA Avancé / Hibernate gratuite par Ippon 2014
Formation JPA Avancé / Hibernate gratuite par Ippon 2014Formation JPA Avancé / Hibernate gratuite par Ippon 2014
Formation JPA Avancé / Hibernate gratuite par Ippon 2014Ippon
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...ENSET, Université Hassan II Casablanca
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJosé Paumard
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring bootAntoine Rey
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)ENSET, Université Hassan II Casablanca
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...ENSET, Université Hassan II Casablanca
 
Concevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootConcevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootDNG Consulting
 
Presentation JEE et son écossystéme
Presentation JEE et son écossystémePresentation JEE et son écossystéme
Presentation JEE et son écossystémeAlgeria JUG
 
Formation Gratuite Total Tests par les experts Java Ippon
Formation Gratuite Total Tests par les experts Java Ippon Formation Gratuite Total Tests par les experts Java Ippon
Formation Gratuite Total Tests par les experts Java Ippon Ippon
 
Formation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataFormation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataLhouceine OUHAMZA
 

La actualidad más candente (20)

Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce  Basé sur Spring IOC MVC Security JPA HibernateSite JEE de ECommerce  Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
 
spring-boot-fr.pdf
spring-boot-fr.pdfspring-boot-fr.pdf
spring-boot-fr.pdf
 
Formation JPA Avancé / Hibernate gratuite par Ippon 2014
Formation JPA Avancé / Hibernate gratuite par Ippon 2014Formation JPA Avancé / Hibernate gratuite par Ippon 2014
Formation JPA Avancé / Hibernate gratuite par Ippon 2014
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
 
Cours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweightCours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweight
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring boot
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
 
Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
 
Support de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfiSupport de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfi
 
Concevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootConcevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring Boot
 
Cours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxyCours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxy
 
Presentation JEE et son écossystéme
Presentation JEE et son écossystémePresentation JEE et son écossystéme
Presentation JEE et son écossystéme
 
Formation Gratuite Total Tests par les experts Java Ippon
Formation Gratuite Total Tests par les experts Java Ippon Formation Gratuite Total Tests par les experts Java Ippon
Formation Gratuite Total Tests par les experts Java Ippon
 
Servlets et JSP
Servlets et JSPServlets et JSP
Servlets et JSP
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
 
Support developpement applications mobiles avec ionic v3 et v4
Support developpement applications mobiles avec ionic v3 et v4Support developpement applications mobiles avec ionic v3 et v4
Support developpement applications mobiles avec ionic v3 et v4
 
Formation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataFormation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-data
 

Destacado

Introduction à Angular JS
Introduction à Angular JSIntroduction à Angular JS
Introduction à Angular JSAntoine Rey
 
Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016Richard Banks
 
Workshop Spring 3 - Tests et techniques avancées du conteneur Spring
Workshop Spring  3 - Tests et techniques avancées du conteneur SpringWorkshop Spring  3 - Tests et techniques avancées du conteneur Spring
Workshop Spring 3 - Tests et techniques avancées du conteneur SpringAntoine Rey
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application javaAntoine Rey
 
Ces outils qui vous font gagner du temps
Ces outils qui vous font gagner du tempsCes outils qui vous font gagner du temps
Ces outils qui vous font gagner du tempsAntoine Rey
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8Antoine Rey
 
Workshop Spring - Session 5 - Spring Integration
Workshop Spring - Session 5 - Spring IntegrationWorkshop Spring - Session 5 - Spring Integration
Workshop Spring - Session 5 - Spring IntegrationAntoine Rey
 
pessimistic-development-presentation
pessimistic-development-presentationpessimistic-development-presentation
pessimistic-development-presentationJonathan Marbutt
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016Antoine Rey
 
Learned optimism
Learned optimismLearned optimism
Learned optimismAndrew Chaa
 
Quoi de neuf à Devoxx France 2017 ?
Quoi de neuf à Devoxx France 2017 ?Quoi de neuf à Devoxx France 2017 ?
Quoi de neuf à Devoxx France 2017 ?Antoine Rey
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample applicationAntoine Rey
 

Destacado (12)

Introduction à Angular JS
Introduction à Angular JSIntroduction à Angular JS
Introduction à Angular JS
 
Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016
 
Workshop Spring 3 - Tests et techniques avancées du conteneur Spring
Workshop Spring  3 - Tests et techniques avancées du conteneur SpringWorkshop Spring  3 - Tests et techniques avancées du conteneur Spring
Workshop Spring 3 - Tests et techniques avancées du conteneur Spring
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application java
 
Ces outils qui vous font gagner du temps
Ces outils qui vous font gagner du tempsCes outils qui vous font gagner du temps
Ces outils qui vous font gagner du temps
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8
 
Workshop Spring - Session 5 - Spring Integration
Workshop Spring - Session 5 - Spring IntegrationWorkshop Spring - Session 5 - Spring Integration
Workshop Spring - Session 5 - Spring Integration
 
pessimistic-development-presentation
pessimistic-development-presentationpessimistic-development-presentation
pessimistic-development-presentation
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016
 
Learned optimism
Learned optimismLearned optimism
Learned optimism
 
Quoi de neuf à Devoxx France 2017 ?
Quoi de neuf à Devoxx France 2017 ?Quoi de neuf à Devoxx France 2017 ?
Quoi de neuf à Devoxx France 2017 ?
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
 

Similar a Les dessous du framework spring

Bean Validation - Cours v 1.1
Bean Validation - Cours v 1.1Bean Validation - Cours v 1.1
Bean Validation - Cours v 1.1Laurent Guérin
 
Spring 3 en production
Spring 3 en productionSpring 3 en production
Spring 3 en productionJulien Dubois
 
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - CoursENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - CoursHoracio Gonzalez
 
20081008 - Tours Jug - Apache Maven
20081008  - Tours Jug - Apache Maven20081008  - Tours Jug - Apache Maven
20081008 - Tours Jug - Apache MavenArnaud Héritier
 
#5 Java EE5 Client Lourd et Smart Client
#5 Java EE5  Client Lourd  et Smart Client#5 Java EE5  Client Lourd  et Smart Client
#5 Java EE5 Client Lourd et Smart ClientGuillaume Sauthier
 
BordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaBordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaCamblor Frédéric
 
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8 Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8 Mickaël Rémond
 
Liferay france symposium 2012 - montée de version d’une instance liferay
Liferay france symposium 2012 - montée de version d’une instance liferayLiferay france symposium 2012 - montée de version d’une instance liferay
Liferay france symposium 2012 - montée de version d’une instance liferaySébastien Le Marchand
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...Publicis Sapient Engineering
 
20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation MavenArnaud Héritier
 
Common features in webapi aspnetcore
Common features in webapi aspnetcoreCommon features in webapi aspnetcore
Common features in webapi aspnetcoreMSDEVMTL
 
Spring Meetup Paris - Back to the basics of Spring (Boot)
Spring Meetup Paris - Back to the basics of Spring (Boot)Spring Meetup Paris - Back to the basics of Spring (Boot)
Spring Meetup Paris - Back to the basics of Spring (Boot)Eric SIBER
 
Présentation de JavaServer Faces
Présentation de JavaServer FacesPrésentation de JavaServer Faces
Présentation de JavaServer FacesJS Bournival
 
Prsentation de-javaserver-faces4124
Prsentation de-javaserver-faces4124Prsentation de-javaserver-faces4124
Prsentation de-javaserver-faces4124Mejdeddine Bouzouita
 
cours8-GL-minfo-1718.pdf
cours8-GL-minfo-1718.pdfcours8-GL-minfo-1718.pdf
cours8-GL-minfo-1718.pdfSliimAmiri
 

Similar a Les dessous du framework spring (20)

Bean Validation - Cours v 1.1
Bean Validation - Cours v 1.1Bean Validation - Cours v 1.1
Bean Validation - Cours v 1.1
 
Spring 3 en production
Spring 3 en productionSpring 3 en production
Spring 3 en production
 
2
22
2
 
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - CoursENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
 
20081008 - Tours Jug - Apache Maven
20081008  - Tours Jug - Apache Maven20081008  - Tours Jug - Apache Maven
20081008 - Tours Jug - Apache Maven
 
#5 Java EE5 Client Lourd et Smart Client
#5 Java EE5  Client Lourd  et Smart Client#5 Java EE5  Client Lourd  et Smart Client
#5 Java EE5 Client Lourd et Smart Client
 
BordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaBordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets Java
 
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8 Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
 
Liferay france symposium 2012 - montée de version d’une instance liferay
Liferay france symposium 2012 - montée de version d’une instance liferayLiferay france symposium 2012 - montée de version d’une instance liferay
Liferay france symposium 2012 - montée de version d’une instance liferay
 
Présentation nouveauté java7
Présentation nouveauté java7Présentation nouveauté java7
Présentation nouveauté java7
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
 
20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven
 
Common features in webapi aspnetcore
Common features in webapi aspnetcoreCommon features in webapi aspnetcore
Common features in webapi aspnetcore
 
Alt.net spring.net
Alt.net spring.netAlt.net spring.net
Alt.net spring.net
 
Alt.net spring.net
Alt.net spring.netAlt.net spring.net
Alt.net spring.net
 
Spring.NET
Spring.NETSpring.NET
Spring.NET
 
Spring Meetup Paris - Back to the basics of Spring (Boot)
Spring Meetup Paris - Back to the basics of Spring (Boot)Spring Meetup Paris - Back to the basics of Spring (Boot)
Spring Meetup Paris - Back to the basics of Spring (Boot)
 
Présentation de JavaServer Faces
Présentation de JavaServer FacesPrésentation de JavaServer Faces
Présentation de JavaServer Faces
 
Prsentation de-javaserver-faces4124
Prsentation de-javaserver-faces4124Prsentation de-javaserver-faces4124
Prsentation de-javaserver-faces4124
 
cours8-GL-minfo-1718.pdf
cours8-GL-minfo-1718.pdfcours8-GL-minfo-1718.pdf
cours8-GL-minfo-1718.pdf
 

Les dessous du framework spring

  • 1. Les dessous du framework Spring 3 décembre 2015
  • 2. Objectifs  Exploiter certaines fonctionnalités méconnues de Spring  Découvrir le fonctionnement interne du conteneur  Eviter certains pièges  Apprendre à partir d’exemples concrets issus d’applications métiers
  • 3. Sommaire  Post-processeurs et fabriques de beans Spring  Intercepteur transactionnel et pièges de l’annotation @Transactional  Lever des ambiguïtés lors de l’injection de beans  Injection de beans de portées différentes  Hiérarchie de contextes Spring  Créer sa propre annotation  Architecture pluggable  Accès au contexte Spring
  • 4.  Caractéristiques o Appelé pendant le processus de création de tout bean Spring o Implémente l’interface BeanPostProcessor o 2 méthodes appelées avant et après la méthode d’initialisation du bean o Peuvent être ordonnés  Etapes de mise à disposition d’un bean 1. Création du bean par constructeur ou appel de méthode statique 2. Valorisation des propriétés du bean 3. Résolution des références vers d’autres beans (wiring) 4. Appel de la méthode postProcessBeforeInitialization() de chaque post-processor 5. Appel des méthodes d’initialisation du bean (@PostConstruct, afterPropertiesSet) 6. Appel de la méthode postProcessAfterInitialization() de chaque post-processor 7. Le bean est prêt à être utilisé par le conteneur Les post-processeurs de bean (1/5)
  • 5. Les post-processeurs de bean (2/5) Chargement en mémoire de la définition des beans XML Conf Spring Java Classes annotées Instanciation du bean ou appel de la fabrique beans  Etapes de mise à disposition des beans de portées singleton d’une application Pour chaque bean trouvé Appel des setters Injection de beans * postProcess BeforeInitialization Pour chaque BeanPost Processor * Initalisation Bean prêt à l’emploi postProcess AfterInitialization afterPropertiesSet @PostConstruct * Possibilités multiples : 1. modifier un bean 2. renvoyer un proxy 3. ajouer un intercepteur
  • 6.  Usage des post-processeurs par Spring et des frameworks tiers Les post-processeurs de bean (3/5) Post-Processeur Description AutowiredAnnotationBeanPostProcessor Active l’auto-wiring via les annotations @Autowired ou @Inject CommonAnnotationBeanPostProcessor Active la détection des annotations de la JSR-250 AsyncAnnotationBeanPostProcessor Active la détection de l’annotation @Async ScheduledAnnotationBeanPostProcessor Active la détection de l’annotation @Scheduled JmsListenerAnnotationBeanPostProcessor Active la détection de l’annotation @JmsListener ApplicationContextAwareProcessor Permet de passer le contexte applicatif Spring aux beans implémentant l’interface ApplicationContextAware ScriptFactoryPostProcessor Permet d’accéder au résultat de scripts (Groovy, JRuby ) BusExtensionPostProcessor Active la détection automatique d’extension de bus CXF JaxWsWebServicePublisherBeanPostProcessor Support CXF des annotations JAX-WS CamelBeanPostProcessor Intégration de beans Spring dans Apache Camel
  • 7.  Exemple d’utilisation  Disposer d’une annotation @Alias se substituant à la syntaxe XML  Demande d’évolution SPR-6736  Définition d’un alias en XML :  Equivalent en annotation : Les post-processeurs de bean (4/5) <bean id="movieController" class="MovieController"/> <alias name="movieController" alias="filmController"/> @Controller("movieController") @Alias("filmController") public class MovieController { }
  • 8.  Mise en œuvre d’un AliasPostProcessor Les post-processeurs de bean (5/5) @Target(TYPE) @Retention(RUNTIME) @Documented public @interface Alias { String value(); } public class AliasPostProcessor implements BeanPostProcessor, BeanFactoryPostProcessor { private ConfigurableListableBeanFactory configurableBeanFactory; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { Class<?> targetClass = AopUtils.getTargetClass(bean); Annotation annotation = targetClass.getAnnotation(Alias.class); if (annotation != null) { configurableBeanFactory.registerAlias(beanName, ((Alias) annotation).value()); } return bean; }
  • 9.  Lors du mécanisme d’injection, met un bean à disposition du conteneur  Instancie ou réutilisation des beans (partage)  Massivement utilisé par le conteneur Spring  Exemple : HibernateSessionFactoryBean  Implémente l’interface FactoryBean  Ce n’est pas la fabrique qui est injectée mais le bean créé par la fabrique (méthode getObject()) Fabrique de beans Spring (1/3)
  • 10.  Exemple d’une fabrique fusionnant des listes de beans  Input : plusieurs listes de beans Spring  Output : une seule liste de beans Spring  Utilisation avec la syntaxe XML : Fabrique de beans Spring (2/3) <bean id="annotatedClasses" class="ListMerger"> <property name="sourceLists"> <util:list> <ref bean="customerAnnotatedClasses" /> <ref bean="aggreementAnnotatedClasses" /> </util:list> </property> </bean>
  • 11.  Implémentation de la fabrique fusionnant des listes de beans Fabrique de beans Spring (3/3) public class ListMerger<V> implements FactoryBean<List<V>> { private List<V> result = new ArrayList<V>(); @Override public List<V> getObject() { return result; } @Override public boolean isSingleton() { return true; } @Override public Class<?> getObjectType() { return List.class; } public void setSourceLists(List<List<V>> sourceLists) { for (List<V> l : sourceLists) { this.result.addAll(l); } } }
  • 12. Points de vigilance avec @Transactional (1/2)  L’annotation @Transactional permet de délimiter des transactions  Point 1 : Commit ou Rollback ? @Transactional public void addMovie(Movie movie) throws BusinessException { movieDao.save(movie); throw new BusinessException(); } @Transactional public void addMovie(Movie movie) throws BusinessException { movieDao.save(movie); throw new TechnicalException(); } Par défaut, lorsqu’une checked exception est levée, Spring valide la transaction Remédiation : utilisation du rollbackFor @Transactional(rollbackFor = Exception.class) ou création d’une annotation dédiée @MyTransactional Commit Rollback
  • 13. Points de vigilance avec @Transactional (2/2)  Point 2: le film est-il sauvegardé dans une transaction ? @Service public class MovieService { @Autowired IMovieDao movieDao; public void addThenIndexMovie(Movie movie) { addMovie(movie); indexMovie(movie); } @Transactional public void addMovie(Movie movie) { … } private void indexMovie(Movie movie) { … } } @RequestMapping(value = "/movie/new") public String create(@Valid Movie movie) { movieService.addThenIndexMovie(movie); return "redirect:/movie/" + movie.getId(); } @RequestMapping(value = "/movie/new") public String create(@Valid Movie movie) { movieService.addMovie(movie); return "redirect:/movie/" + movie.getId(); }  Scénario 1 : appel direct à addMovie  Scénario 2 : appel indirect à addMovie Transactionnel Non transactionnel
  • 14.  Lors de l’injection de beans, Spring peut modifier la chaîne d’appel  Design Pattern Proxy ou Intercepteur  Exemples d’usage :  Greffer des aspects  Insérer un comportement transactionnel  2 types de proxy en fonction de l’appelé :  Interface par l’utilisation de proxy dynamique java.lang.reflect.Proxy  Classe par instrumentation de code Intercepteur transactionnel (1/2)
  • 15. Intercepteur transactionnel (2/2) MovieController JdkDynamicAopProxy TransactionInterceptor MovieService addMovie invoke addMovie Ouverture d’une transaction car addMovie annoté addThenIndexMovie addThenIndexMovie addMovie Pas de transaction car on ne repasse pas par le proxy
  • 16. Levée d’ambiguité avec @Primary (1/2)  2 implémentations d’une même interface @Service public class NetflixService implements IMovieService { } @Service public class ImdbService implements IMovieService { }  Spring est incapable de déterminer quel bean injecter @Autowired private IMovieService movieService; NoUniqueBeanDefinitionException : expected single matching bean but found 2: imdbService,netflixService
  • 17. Levée d’ambiguité avec @Primary (2/2)  Solution 1 : utilisation d’un qualifier @Autowired @Qualifier("netflixService") private IMovieService movieService;  Solution 2 : définition d’un bean principal (bean par défaut) @Service @Primary public class NetflixService implements IMovieService { }  Permet de ne pas alourdir l’injection de dépendance lorsque dans la plupart des cas c’est le bean netflixService qui doit être injecté.  Autres exemples : DataSourceTransactionManager vs JmsTransactionManager NetflixService vs MockMovieService
  • 18.  Comment injecter un bean de portée session dans un singleton ?  Rappels  Un bean de portée Singleton  doit d’être thread-safe  est créé au démarrage du conteneur  Un bean de portée session est créé pour chaque session web utilisateur  Cas d’usage  Dans les contrôleurs, ne plus manipuler directement la session HTTP  Toutes les données à mettre en session sont modélisées dans un ou plusieurs beans  Avoir accès dans un service métier aux informations de l’utilisateur connecté  Besoin : contrôle des habilitations, historisation, logs  Un bean de portée requête peut remplacer l’utilisation du ThreadLocal Injection de beans de portée différente (1/3)
  • 19.  Solution  Proxifier le bean de portée Session  Le proxy est chargé d’aiguiller les appels vers le bean session approprié  Illustration Injection de beans de portée différente (2/3) Service singleton Conteneur Spring Proxy Informations Utilisateur Contrôleur singleton James session John session getName() getName()
  • 20.  Exemples de mise en oeuvre Injection de beans de portée différente (3/3) @Configuration public class UserConfig { @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public UserDetails userDetails() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return (UserDetails) authentication.getPrincipal(); } } @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class MovieModelView { private Movie selectedMovie; private String email; … }
  • 21.  Les scopes request et session n’ont de sens que dans un conteneur web  Erreur lorsqu’ils sont utilisés dans un simple ApplicationContext  java.lang.IllegalStateException: No Scope registered for scope 'session’ Tests de beans de portée web @WebAppConfiguration @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class TestWebScope {  Solution 1 : l’annotation @WebAppConfiguration  Solution 2 : déclarer un bean CustomScopeConfigurer et utiliser le scope SimpleThreadScope @Configuration static class Config { @Bean public CustomScopeConfigurer customScopeConfigurer() { CustomScopeConfigurer csc = new CustomScopeConfigurer(); Map<String, Object> map = new HashMap<String, Object>(); map.put("session", new SimpleThreadScope()); map.put("request", new SimpleThreadScope()); csc.setScopes(map); return csc; } }
  • 22.  Une application Spring est composée d’un ou plusieurs contextes applicatifs  Les contextes applicatifs Spring peuvent être hiérarchiques  C’est typiquement le cas dans les applications web basées sur Spring MVC Hiérarchie de contextes (1/4) Root WebApplicationContext DAO Services métiers Child WebApplicationContext Contrôleurs IHM Child WebApplicationContext Contrôleurs REST
  • 23.  Les beans déclarés dans le contexte parent sont visibles des contextes enfants  Respect du découpage en couche  Alternative aux multi-wars  Chargement du contexte parent depuis un listener JEE déclaré dans le web.xml : Hiérarchie de contextes (2/4) <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/business-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
  • 24.  Chargement des contextes enfants via les DispatcherServlet déclarés dans le web.xml Hiérarchie de contextes (3/4) <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web .servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.web .servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:rest-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/rest</url-pattern> </servlet-mapping>
  • 25.  L’annotation @ContextHierarchy rend possible l’écriture de tests d’intégration avec hiérarchie de contextes Hiérarchie de contextes (4/4) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(name = "parent", locations = "classpath:business-config.xml"), @ContextConfiguration(name = "child", locations = "classpath:spring-mvc-config.xml") }) public class SpringConfigTest { @Autowired private WebApplicationContext childContext; @Test public void parentChildContext) { ApplicationContext parentContext = childContext.getParent(); assertTrue(parentContext.containsBean("myService")); assertTrue(childContext.containsBean("myService")); assertFalse(parentContext.containsBean("myController")); assertTrue(childContext.containsBean("myController")); } }
  • 26.  Possibilité d’étendre le jeu d’annotations @Component, @Service, @Repository et @Controller  Exemple d’annotation utilisée sur les classes de mapping objet-objet : Créer sa propre annotation @Component @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Mapper { String value() default ""; } @Pointcut("within(@com.mycompagny.spring.Mapper *)") public void mapper() { /**/ }  Exemple d’utilisation en AOP dans les points de coupe :
  • 27.  Spring permet d’injecter une collection de beans du même type Architecture pluggable @Service public class PluginManager { @Autowired private List<IPlugin> pluginList; @Autowired private Map<String, IPlugin> pluginMap; }  Mécanisme d’extension très simple  Exemple : ajout de nouveaux formats de fichiers dans un composant d’upload de fichiers
  • 28.  Depuis une Servlet Accès au contexte Spring public class MovieServlet extends HttpServlet { private IMovieService movieService; @Override public void init() throws ServletException { ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); movieService = applicationContext.getBean(IMovieService.class); } @Component public class MonBean { @Autowired private ApplicationContext applicationContext;  Depuis un bean Spring public class MonBean implements ApplicationContextAware { @Override public void setApplicationContext( ApplicationContext applicationContext) { this.applicationContext = applicationContext; }
  • 29. Conclusion  Les mécanismes utilisés en interne par Spring permettent d’étendre les fonctionnalités du framework  Connaître le fonctionnement des proxy et des intercepteurs permet d’éviter des bugs  Dans une application web, la portée des beans doit être choisie judicieusement

Notas del editor

  1. Démystifier le côté magique de certains comportements (ex: @Async)
  2. Les directives XML telles que <context;annotation-config> activent une ou plusieurs BPP Ordre déterminé par l’interfacr Ordered Post-processeurs couramment utilisés dans Spring : CommonAnnotationBeanPostProcessor : active la détection des annotations de la JSR-250 utilisées notamment pour les méthodes d’initialisation, de destruction et l’autowiring de ressources JEE. RequiredAnnotationBeanPostProcessor : active la détection de l’annotation @Required qui permet de préciser les propriétés obligatoires dans un Bean. AsyncAnnotationBeanPostProcessor : active la détection de l’annotation @Async qui permet d’exécuter des méthodes en asynchrone
  3. Les directives XML telles que <context;annotation-config> activent une ou plusieurs BPP Ordre déterminé par l’interfacr Ordered Post-processeurs couramment utilisés dans Spring : CommonAnnotationBeanPostProcessor : active la détection des annotations de la JSR-250 utilisées notamment pour les méthodes d’initialisation, de destruction et l’autowiring de ressources JEE. RequiredAnnotationBeanPostProcessor : active la détection de l’annotation @Required qui permet de préciser les propriétés obligatoires dans un Bean. AsyncAnnotationBeanPostProcessor : active la détection de l’annotation @Async qui permet d’exécuter des méthodes en asynchrone
  4. Autre exemple d’utilisation bien plus complexe : mécanisme de notification
  5. BeanFactoryPostProcessor permet d’avoir accès au ConfigurableListableBeanFactory
  6. Utilisation : création de beans complexes Autres exemples : TransactionProxyFactoryBean, EhCacheFactoryBean, ThreadPoolExecutorFactoryBean, VelocityEngineFactoryBean
  7. Combinaison fréquente : annotation + fabrique de beans