Julien Sadaoui
@juliensadaoui @ippontech
Injection de dépendances et
type-safe binding avec Spring
Type-safe avec Spring ?
Pourquoi ?
● Typage fort sur nos dépendances
● Comportement similaire à CDI (JSR 299)
Comment ?
● Utilisation de @Qualifier depuis Spring 2.5
● Ou @javax.inject.Qualifier depuis Spring 3.0
Use cases
● Un service de paiement peut effectuer une transaction
bancaire de plusieurs façons différentes, selon le moyen de
paiement du client.
Injection avec Spring
Injection classique
@Service
public class PaymentServiceImpl implements PaymentService {
// ...
}
public class PaymentClient {
@Autowired
private PaymentService paymentService;
}
Cas le plus simple et le plus classique :
un seul bean d’un certain type,
et un point d’injection avec ce type ...
Plusieurs implémentations ...
@Service
public class MasterCardPaymentService implements PaymentService {
// ...
}
@Service
public class VisaPaymentService implements PaymentService {
// ...
}
public class PaymentClient {
@Autowired
private PaymentService paymentService;
}
Plusieurs implémentations ...
@Service
public class MasterCardPaymentService implements PaymentService {
// ...
}
@Service
public class VisaPaymentService implements PaymentService {
// ...
}
public class PaymentClient {
@Autowired // ambiguïté sur le point d'injection
private PaymentService paymentService;
}
Résolution avec le nom du bean
public class PaymentClient {
@Inject
private PaymentService visaPaymentService;
}
public class PaymentClient {
@Inject
@Qualifier(“visaPaymentService”)
private PaymentService paymentService;
}
● Le nom de la variable associé au point d’injection
● Lever l'ambiguïté avec l’annotation @Qualifier
Nommage des beans
@Service(“visa”)
public class VisaPaymentService implements PaymentService {
// ...
}
@Service => visaPaymentService
public class VisaPaymentService implements PaymentService {
// ...
}
● Spécifier le nom avec l’attribut “value” @Service
● Par défaut, c’est le nom de classe non qualifié
Résolution avec @Qualifier
@Service
@Qualifier(“visa”)
public class VisaCardPaymentService implements PaymentService {
// ...
}
public class PaymentClient {
@Inject
@Qualifier(“visa”)
private PaymentService paymentService;
}
● On peut qualifier explicitement un bean avec l’annotation
Qualifier (ne correspond pas à son nom)
Injection avec @Qualifier
Injection avec @Qualifier
@Target({FIELD, TYPE, METHOD, PARAMETER})
@Retention(RUNTIME)
@Qualifier
public @interface MasterCard {
}
@Target({FIELD, TYPE, METHOD, PARAMETER})
@Retention(RUNTIME)
@Qualifier
public @interface Visa {
}
Injection avec @Qualifier
@Service
@MasterCard
public class MasterCardPaymentService implements PaymentService {
// ...
}
@Service
@Visa
public class VisaPaymentService implements PaymentService {
// ...
}
Injection avec @Qualifier
public class PaymentResource {
@Autowired @Visa
private PaymentService visa;
@Autowired @MasterCard
private PaymentService masterCard;
// ...
}
Qualifier avec membres
Qualifier avec membres
@Target({FIELD,TYPE,METHOD,PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Payment {
PaymentMethod value();
public static enum PaymentMethod {
VISA,
MASTER_CARD,
PAYPAL
}
}
Qualifier avec membres
@Service
@Payment(PaymentMethod.VISA)
public class VisaPaymentService implements PaymentService {
// ...
}
@Service
@Payment(PaymentMethod.PAYPAL)
public class PaypalPaymentService implements PaymentService {
// ...
}
Qualifier avec membres
public class PaymentClient {
@Autowired
@Payment(PaymentMethod.VISA)
private PaymentService visa;
@Autowired
@Payment(PaymentMethod.PAYPAL)
private PaymentService paypal;
// ...
}
Support de la JSR 330
Support de la JSR 330
● API légère pour l’injection de dépendances
● On peut utiliser les annotations standards de la JSR 330
depuis Spring 3.0
Spring javax.inject.*
@Autowired @Inject
@Component @Named
@Qualifier @Qualifier
Support de la JSR 330
@Target({FIELD,TYPE,METHOD,PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@javax.inject.Qualifier
public @interface Payment {
PaymentMethod value();
public static enum PaymentMethod {
VISA,
MASTER_CARD,
PAYPAL
}
}
Support de la JSR 330
@Named
@Payment(PaymentMethod.VISA)
public class VisaPaymentService implements PaymentService {
// ...
}
@Named
@Payment(PaymentMethod.PAYPAL)
public class PaypalPaymentService implements PaymentService {
// ...
}
Support de la JSR 330
public class PaymentService {
@Inject
@Payment(PaymentMethod.VISA)
private PaymentService visa;
@Inject
@Payment(PaymentMethod.PAYPAL)
private PaymentService paypal;
// ...
}
Conclusion
● Plus propre comme injection
● Couplage faible avec typage fort
● Utilisation des annotations à la place des chaînes
de caractères
● Disponible depuis Spring 2.5
● Compatible avec la JSR 330
Liens utiles
Guide de références
http://docs.spring.io/spring/docs/current/spring-framework-
reference/htmlsingle/#beans-autowired-annotation-qualifiers
Blogs de spring
http://spring.io/blog/2014/11/04/a-quality-qualifier
Exemples des slides
https://github.com/juliensadaoui/ippevent2015-youngblood
@juliensadaoui
juliensadaoui
@ippontech
blog.ippon.fr

Ippevent Young Blood - Injection de dépendance et type safe binding avec spring

  • 1.
    Julien Sadaoui @juliensadaoui @ippontech Injectionde dépendances et type-safe binding avec Spring
  • 2.
    Type-safe avec Spring? Pourquoi ? ● Typage fort sur nos dépendances ● Comportement similaire à CDI (JSR 299) Comment ? ● Utilisation de @Qualifier depuis Spring 2.5 ● Ou @javax.inject.Qualifier depuis Spring 3.0
  • 3.
    Use cases ● Unservice de paiement peut effectuer une transaction bancaire de plusieurs façons différentes, selon le moyen de paiement du client.
  • 4.
  • 5.
    Injection classique @Service public classPaymentServiceImpl implements PaymentService { // ... } public class PaymentClient { @Autowired private PaymentService paymentService; } Cas le plus simple et le plus classique : un seul bean d’un certain type, et un point d’injection avec ce type ...
  • 6.
    Plusieurs implémentations ... @Service publicclass MasterCardPaymentService implements PaymentService { // ... } @Service public class VisaPaymentService implements PaymentService { // ... } public class PaymentClient { @Autowired private PaymentService paymentService; }
  • 7.
    Plusieurs implémentations ... @Service publicclass MasterCardPaymentService implements PaymentService { // ... } @Service public class VisaPaymentService implements PaymentService { // ... } public class PaymentClient { @Autowired // ambiguïté sur le point d'injection private PaymentService paymentService; }
  • 8.
    Résolution avec lenom du bean public class PaymentClient { @Inject private PaymentService visaPaymentService; } public class PaymentClient { @Inject @Qualifier(“visaPaymentService”) private PaymentService paymentService; } ● Le nom de la variable associé au point d’injection ● Lever l'ambiguïté avec l’annotation @Qualifier
  • 9.
    Nommage des beans @Service(“visa”) publicclass VisaPaymentService implements PaymentService { // ... } @Service => visaPaymentService public class VisaPaymentService implements PaymentService { // ... } ● Spécifier le nom avec l’attribut “value” @Service ● Par défaut, c’est le nom de classe non qualifié
  • 10.
    Résolution avec @Qualifier @Service @Qualifier(“visa”) publicclass VisaCardPaymentService implements PaymentService { // ... } public class PaymentClient { @Inject @Qualifier(“visa”) private PaymentService paymentService; } ● On peut qualifier explicitement un bean avec l’annotation Qualifier (ne correspond pas à son nom)
  • 11.
  • 12.
    Injection avec @Qualifier @Target({FIELD,TYPE, METHOD, PARAMETER}) @Retention(RUNTIME) @Qualifier public @interface MasterCard { } @Target({FIELD, TYPE, METHOD, PARAMETER}) @Retention(RUNTIME) @Qualifier public @interface Visa { }
  • 13.
    Injection avec @Qualifier @Service @MasterCard publicclass MasterCardPaymentService implements PaymentService { // ... } @Service @Visa public class VisaPaymentService implements PaymentService { // ... }
  • 14.
    Injection avec @Qualifier publicclass PaymentResource { @Autowired @Visa private PaymentService visa; @Autowired @MasterCard private PaymentService masterCard; // ... }
  • 15.
  • 16.
    Qualifier avec membres @Target({FIELD,TYPE,METHOD,PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public@interface Payment { PaymentMethod value(); public static enum PaymentMethod { VISA, MASTER_CARD, PAYPAL } }
  • 17.
    Qualifier avec membres @Service @Payment(PaymentMethod.VISA) publicclass VisaPaymentService implements PaymentService { // ... } @Service @Payment(PaymentMethod.PAYPAL) public class PaypalPaymentService implements PaymentService { // ... }
  • 18.
    Qualifier avec membres publicclass PaymentClient { @Autowired @Payment(PaymentMethod.VISA) private PaymentService visa; @Autowired @Payment(PaymentMethod.PAYPAL) private PaymentService paypal; // ... }
  • 19.
  • 20.
    Support de laJSR 330 ● API légère pour l’injection de dépendances ● On peut utiliser les annotations standards de la JSR 330 depuis Spring 3.0 Spring javax.inject.* @Autowired @Inject @Component @Named @Qualifier @Qualifier
  • 21.
    Support de laJSR 330 @Target({FIELD,TYPE,METHOD,PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @javax.inject.Qualifier public @interface Payment { PaymentMethod value(); public static enum PaymentMethod { VISA, MASTER_CARD, PAYPAL } }
  • 22.
    Support de laJSR 330 @Named @Payment(PaymentMethod.VISA) public class VisaPaymentService implements PaymentService { // ... } @Named @Payment(PaymentMethod.PAYPAL) public class PaypalPaymentService implements PaymentService { // ... }
  • 23.
    Support de laJSR 330 public class PaymentService { @Inject @Payment(PaymentMethod.VISA) private PaymentService visa; @Inject @Payment(PaymentMethod.PAYPAL) private PaymentService paypal; // ... }
  • 24.
    Conclusion ● Plus proprecomme injection ● Couplage faible avec typage fort ● Utilisation des annotations à la place des chaînes de caractères ● Disponible depuis Spring 2.5 ● Compatible avec la JSR 330
  • 25.
    Liens utiles Guide deréférences http://docs.spring.io/spring/docs/current/spring-framework- reference/htmlsingle/#beans-autowired-annotation-qualifiers Blogs de spring http://spring.io/blog/2014/11/04/a-quality-qualifier Exemples des slides https://github.com/juliensadaoui/ippevent2015-youngblood
  • 26.