Canonical way to obtain CDI managed bean instance: BeanManager#getReference() vs Context#get()

点点圈 提交于 2019-11-29 20:36:09
Asif Bhutto

beanManager#getReference gives you a new instance of a client proxy but the client proxy will forward method calls to the current contextual instance of a particular context. Once you obtain the proxy and keep it and the method calls will be invoked on the current instance (e.g. current request). It is also useful if the contextual instance is not serializable - the client proxy will be and will reconnect after you deserialize it.

BeanManager#getContext obtains the target instance without a client proxy. You may still see a Weld's proxy in the class name but that is an enhanced subclass that provides interception and decoration. If the bean is not intercepted nor decorated this will be a plain instance of the given bean.

Usually (1) is more suitable unless you have a special use-case where you need to access the target instance directly (e.g. to access its fields).

Or in other words

1) BeanManager#getReference will return a 'Contextual Reference', with a normal scoping proxy for the bean. If a bean have with @SessionScoped as

@SessionScoped User user;

Then the contextual reference user will 'point' to the respective User instance (the 'Contextual Instance') of the current session for each invocation. Two different invocations to user.getName() from two different web browsers will give you different answers.

2) Context#get() will return a the internal 'Contextual Instance' without the normal scoping proxy.This is usually nothing a user should call himself. If you get the User user for "Bob" that way and store it in an @ApplicationScoped bean or in a static variable, then it will always remain to be the user "Bob" - even for web requests from other browsers! You will get a direct, non-proxied instance.

I have a Singleton that I was using the getReference() method to get the reference to. Even though the singleton was already initialized, the proxy created through getReference() called the @PostConstruct each time getReference() was used.

@Startup
@ApplicationScoped
@Singleton

@PostConstruct
private void initialize() {}

By switching to the getContext().get() method, the unnecessary @PostConstruct proxy calls are no longer made.

brammie

This was very helpful when integrating CDI with javafx, the thing was that I needed a reference to the right scoped object cause and not the proxy of the dependent scope...

I used a producer method to get a javaFX Node that gets injected into the controler like so:

@Inject
@ApplicationScoped
@FXMLFile("javafx/wares.fxml")
@FXMLController(WaresController.class)
Parent wares;

but when using the BeanManager#getReference() the proxy I get back "eats" all the values that are set by the FXMLLoader, the getContext.get() way solved it.

Thnx for this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!