EJB 3.1. Is @Local annotation needed?

2020-06-17 04:38发布

问题:

So far, I almost always worked with no-interface EJBs and have a slight understanding about the need of @Local annotation. Consider this example:

public interface MyBeanIntf { void doStuff(); }

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }

Should the MyBeanIntf be marked as @Local? I don't see any benefit from that, because even when I don't annotate it as @Local, I still can use DI to properly inject it into UI Controller:

@Named
@SessionScoped
public class TestController implements Serializable {

  // injection works perfectly, even when MyBeanIntf is not marked as @Local
  @Inject
  private MyBeanIntf myBean;

  // or even like this:
  // @EJB
  // private MyBeanIntf myBean;

}

Let's make it more complex:

public interface MyBeanIntf { void doStuff(); }
public class MySuperBean implements MyBeanIntf { public void doStuff() { } }

@Stateless
public class MyBean extends MySuperBean { }

Is MyBean now considered a valid Local EJB bean? I have some doubts because it implements the interface indirectly.

回答1:

If your EJB implements some interface but you don't specify (neither on the EJB nor the interface itself) which interface it is (@Remote, @Local) than it's assumed that it's a @Local one.

Therefore your code:

public interface MyBeanIntf { void doStuff(); }

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }

is semantically identical to the following:

@Local
public interface MyBeanIntf { void doStuff(); }

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }

When it comes to the second part of your question, I think that section 4.9.2.1 Session Bean Superclasses from EJB 3.1 FR spec would be interesting for you. From my understanding (so it might not be correct), it seems that your bean should not be considered as exposing a valid Local interface because of the following excerpt:

@Stateless
public class A implements Foo { ... }

@Stateless
public class B extends A implements Bar { ... }

Assuming Foo and Bar are local business interfaces and there is no associated deployment descriptor, session bean A exposes local business interface Foo and session bean B exposes local business interface Bar, but not Foo.

Session bean B would need to explicitly include Foo in its set of exposed views for that interface to apply.

Update:

As an addition one more excerpt from the spec:

A session bean class is permitted to have superclasses that are themselves session bean classes. However, there are no special rules that apply to the processing of annotations or the deployment descriptor for this case. For the purposes of processing a particular session bean class, all superclass processing is identical regardless of whether the superclasses are themselves session bean classes.