简体   繁体   中英

EJB 3.1 - Why sateless bean must be injected by its interface (if there is one)?

Since EJB 3.1, beans don't need to have a Local interface, and I usually don't use one:

@Stateless
public class MyService(){
    public void buisnesssMethodA(){
        ...
    }

    public void buisnesssMethodB(){
        ...
    }
}

and in my CDI bean I just do

@Inject
private MyService myService;

This is easy and simple and it works just fine.

Now I have recently discovered something.

Imagine I need an interface that represents a subset of my business method.

public interface MyInterface{
    void businessMethodA();
}

Now if I make my Stateless bean implement this interface, JBoss fails to deploy and throws the error

WELD-001408 Unsatisfied dependencies for type [MyService] with qualifiers [@Default] at injection point [[field] @Inject

So I believe I'm observing the following rule:

If a stateless bean doesn't have an interface it can be injected using the class. If it implements an interface it must be injected using the interface.

Here are my questions:

  1. Is this rule correct?
  2. If so is it defined by the EBJ specs?
  3. What would be the reason for this restriction?

From my limited knowledge of Java EE and CDI:

  • CDI does not manage EJB 3.1 stateless session beans by itself (it wouldn't have all the lifecycle and interceptors) but it can @Inject exposed local views of those beans
  • session bean may expose local business interface view if it has an interface or no-interface view (consisting of beans public methods)
  • in Java EE 7 when session bean does not implement any interface, by default it exposes no-interface view - hence you could inject MyService without interface. This is equivalent to annotating bean with @LocalBean. Note that with @LocalBean you expose no-inerface view even if the bean class implements an interface - hence the comment from Tom worked
  • in Java EE 7 if the session bean implements an interface and is not marked @LocalBean, this interface is by default exposed as local view of the bean - hence you could not inject MyService after it implemented MyInterface, since no-interface view (MyService) was no longer exposed, and interface view MyInterface was exposed as local view instead

Hope this answers your question 3, and partly confirms, partly invalidates your rule from questoin 1. I cannot be bothered now to answer question 2 though...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM