Forma canônica de obter a instância do bean gerenciado CDI: BeanManager # getReference () vs Context # get ()

Eu percebi que existem duas maneiras gerais de obter uma instância de bean gerenciado CDI criado automaticamenteBeanManager quando tendo apenas umBean<T> para começar (que é criado com base emClass<T>):

PorBeanManager#getReference(), que é mais frequentemente mostrado em fragmentos:

Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
TestBean testBean1 = (TestBean) beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));

PorContext#get(), que é menos exibido em snippets:

Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
TestBean testBean2 = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean));

Em efeito, eles fazem exatamente a mesma coisa: retornar uma referência com proxy para a instância atual do bean gerenciado por CDI e criar automaticamente a instância do bean, se ela ainda não existir no escopo.

Mas eles fazem isso de maneira um pouco diferente: oBeanManager#getReference() sempre cria uma nova instância de proxy, enquanto oContext#get() reutiliza uma instância de proxy existente, se já criada antes. Isto é evidente quando o código acima é executado em um método de ação de umTestBean instância:

System.out.println(testBean1 == testBean2); // false
System.out.println(testBean1 == this); // false
System.out.println(testBean2 == this); // true

ojavadoc doContext#get() é muito explícito nisso:

Retorna uma instância existente de determinado tipo contextual ou cria uma nova instância chamando Contextual.create (CreationalContext) e retorna a nova instância.

enquanto ojavadoc doBeanManager#getReference() não é explícito o suficiente sobre isso:

Obtém uma referência contextual para um determinado bean e um determinado tipo de bean do bean.

Isso me confundiu. Quando você usa um ou outro? Para as duas maneiras vocêprecisar a Bean<T> instância de qualquer maneira, a partir do qual a classe do bean e o escopo do bean estão prontamente disponíveis, o que é necessário como argumento adicional. Não consigo imaginar por que eles precisariam ser fornecidos externamente neste caso específico.

Eu posso imaginar issoContext#get() é mais eficiente em termos de memória, pois não cria desnecessariamente outra instância de proxy referindo-se à mesma instância de bean subjacente, mas apenas encontra e reutiliza uma instância de proxy existente.

Isso me leva à seguinte questão: quando exatamente éBeanManager#getReference() mais útil queContext#get()? É mais freqüentemente mostrado em snippets e mais frequentemente recomendado como solução, mas apenas cria desnecessariamente um novo proxy mesmo quando já existe um.

questionAnswers(3)

yourAnswerToTheQuestion