2017-10-10 16 views
1

Imaginons que je veux un seul not.my.Clock par ma demande:Comment définir un objet singleton pour une classe que je n'ai pas écrite en Java EE?

public final class Clock { 
    ... // business 
} 

Je peux écrire ce qui suit:

@Singleton 
public class ClockProvider implements Supplier<Clock> { 
    private Clock clock; 
    @PostConstruct 
    void init() { 
    clock = ... ; 
    } 
    @Override 
    public Clock get() { 
    return clock; 
    } 
} 

@RequestScoped 
public class MyBean { 
    @Inject ClockProvider clockProvider; 
    // Use clockProvider.get() 
} 

Comment puis-je définir un objet singleton pour mon application entière au lieu d'un fournisseur de singleton, afin que je puisse écrire le code suivant? Le tutoriel Java EE 7 only speaks about singleton session bean, not singleton objects.

@RequestScoped 
public class MyBean { 
    @Inject Clock clock; 
    // Use clock directly: no clock-provider. 
} 

Si je devais écrire ce dans Guice, j'écrire quelque chose comme ceci:

bind(Clock.class).toInstance(...); 

Ou

@Provides @Singleton Clock provideClock() { 
    return ... ; 
} 
+0

Ne peut pas vous étendre 'Clock' dans une SingletonClock de classe' @Singleton étend Clock'? – daniu

+1

@daniu Non parce que je reçois l'instance unique d'un endroit où je n'ai pas la main. En outre, j'ai pris 'Clock' comme exemple, pas comme mon cas d'utilisation réel. Mais pour la question, imaginons que la classe 'Clock' soit finale aussi. Je vais adapter la question –

+0

utiliser CDI '@Produces @ ApplicationScoped' sur' public Clock get() 'méthode – Rouliboy

Répondre

1

Vous pouvez utiliser @Produces et @ApplicationScoped annotations sur la méthode public Clock get() pour un produit Clock singleton:

@Produces 
@ApplicationScoped 
public Clock get() { 
    // your code 
} 
1

Avec CDI, vous voulez aller pour @ApplicationScoped (une instance partagée dans votre application) à la place pour @Singleton (avez-vous voulu dire EJB one? ou CDI un?).

Ensuite, vous voulez faire ce que vous faites avec tous les «non-haricots» que vous voulez transformer en haricots - vous dites à CDI comment produire un tel haricot. Avec

@Produces 
@ApplicationScoped 
public Clock produceClock() { 
    Clock clock = ... // any code you use to create or retrieve the instance 
    return clock; 
} 

ci-dessus, vous pouvez alors faire @Inject Clock clock dans votre code qui appellera ce producteur afin de créer la fève.

Si vous souhaitez en savoir plus sur les producteurs, c'est au this chapter in CDI spec.