Should I Use @Ejb or @Inject

Should I use @EJB or @Inject

The @EJB is used to inject EJB's only and is available for quite some time now. @Inject can inject any managed bean and is a part of the new CDI specification (since Java EE 6).

In simple cases you can simply change @EJB to @Inject. In more advanced cases (e.g. when you heavily depend on @EJB's attributes like beanName, lookup or beanInterface) than in order to use @Inject you would need to define a @Producer field or method.

These resources might be helpful to understand the differences between @EJB and @Produces and how to get the best of them:

Antonio Goncalves' blog:

CDI Part I

CDI Part II

CDI Part III

JBoss Weld documentation:

CDI and the Java EE ecosystem

StackOverflow:

Inject @EJB bean based on conditions

What is the difference between @Inject and @EJB

  1. @EJB injects EJBs only, but @Inject can be used to inject POJOs rather than EJBs. However, @Inject requires that your archive be a BDA (contain beans.xml for EE 6, or implicitly in EE 7). @Inject also has additional CDI-specific capabilities (scopes, interceptors, etc.), but those capabilities incur extra overhead. Application servers have support for specifying @EJB bindings so that a deployer can choose the target EJB, but @Inject only allows the application developer to choose the target EJB (and it must exist in the application).

  2. If the target is not an EJB, then you must not use @EJB.

  3. It depends whether you're making multiple inter-related queries and then attempting to make business decisions. You need to understand isolation levels and take them into consideration, even for read-only operations.

Which method to use for injecting EJB?

I have never seen anywhere that you could use @Resource for injecting an EJB. It might work in some servers but it is unlikely to be portable.

The question of @EJB vs @Inject is more complicated.

CDI and @Inject were added to the Java EE 6 Specification. There it was possible to @Inject EJBs into a CDI bean, but not in too many other (if any) places.

The Java EE 7 Specification unified this substantially to the point where you can use @Inject or @EJB interchangeably in most (if not all) places. In essence all of the "sub" specifications such as the EJB spec itself, the servlet spec, JAX-WS, JAX-RS, etc had to be updated to support the use of @Inject as well as @EJB. However if you need to specify any of the attributes available on the @EJB annotation then these are not available on @Inject.

Therefore, feel free to use @Inject anywhere if you're running in a Java EE 7 compliant environment and you don't have a need for any of the @EJB attributes, otherwise use @EJB.

Where is it all allowed to inject EJB?

Here is an extract from Java EE Tutorial:

Dependency injection is the simplest way of obtaining an enterprise bean reference. Clients that run within a Java EE server-managed environment, JavaServer Faces web applications, JAX-RS web services, other enterprise beans, or Java EE application clients, support dependency injection using the javax.ejb.EJB annotation.

Applications that run outside a Java EE server-managed environment, such as Java SE applications, must perform an explicit lookup. JNDI supports a global syntax for identifying Java EE components to simplify this explicit lookup.

EJB bean and CDI bean and Injection

I would make the following corrections:

  1. All classes within the same archive as the beans.xml is a CDI bean, including EJBs.

  2. Only EJB can be injected using @EJB (within another EJB or any other EE managed object including CDI beans), while both CDI bean and EJB bean can be injected using @inject (within EJB bean or CDI bean).

  3. A class annotated as @Stateless (for example) that is injected using @Inject is still an EJB bean, and it may also be a CDI bean if in a bean deployment archive; regardless, it will still be managed by EJB container with all the goodness of pooling and transactional.

Notably, a CDI managed bean is anything that can be @Injected into another CDI bean and can itself use @Inject, which is true for all EJBs, and @EJB can be used to inject an EJB into any other EE managed bean (EJB, servlet, CDI managed bean, etc.).

Can Inject (@EJB) Bean in method of other Bean Session(Remote or Local) class

No, you cant inject into method. You may only use @EJB at class level, field or setter like this:

@Stateless
@EJB(name="myBeanRef", beanInterface=MyBean.class) // this creates only reference - you will need to initialize it for example via initialConetxt.lookup()
public class EJBTests{
@EJB (name=”ejb/bean1”) // this injects bean named ejb/bean1
MyBean1 bean1;

MyBean2 bean2;

....
@EJB (name="ejb/bean2") // this injects bean using setter method
public void setEcho(MyBean2 bean2) {
this.bean2 = bean2;
}
}

For more details check 7.1 @EJB – injecting an EJB from the EJB 3.1 specification.

Injecting EJB with @EJB or @Inject in the service layer for my REST web service?

@Inject supports the injection of EJBs. There is no functional difference, CDI is doing a lookup to find the object using the standard JNDI locations. The @EJB annotation has some additional capabilities, mostly around remoting or non standard JNDI locations that wouldn't be supported OOTB by @Inject

Inject EJB and CDI into Spring-Handler

Normally, you cannot inject CDI managed Bean into Spring managed Bean.
You will need to use direct access to Bean Manager.
For Example by using javax.enterprise.inject.spi.CDI class.

then you can do something like that:

public static <T> T getInstance(Class<T> type, Annotation... qualifiers) {
Set<Bean<?>> beans = getBeanManager().getBeans(type, qualifiers);
Bean<?> bean = getBeanManager().resolve(beans);

if(bean == null){
throw new UnsatisfiedResolutionException();
}

@SuppressWarnings("unchecked")
T instance = (T) getBeanManager().getReference(bean, type,
getBeanManager().createCreationalContext(bean));
return instance;
}

public static BeanManager getBeanManager() {
return CDI.current().getBeanManager();
}


Related Topics



Leave a reply



Submit