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.