案例 1:使用本地业务接口(或无接口视图)
是的,只要您的服务仅由本地业务接口访问,就可以。为什么?本地业务接口只能被本地客户端访问。
本地客户端具有这些特征[LocalClients]。
它必须在与其访问的企业 bean 相同的应用程序中运行。
它可以是一个 Web 组件或另一个企业 bean。
对于本地客户端,它访问的企业 bean 的位置是不透明的。
总结重要特征。它分别在同一个JVM中的同一个应用程序中运行,它是一个Web或EJB组件,并且被访问的bean的位置对于本地客户端是不透明的。请查看LocalClients 了解更多详情。
下面是一个简单的 Hello World 示例。我的示例使用无接口视图,这相当于本地业务接口。
编辑:通过 JNDI 查找扩展的示例。
/** Service class */
import javax.ejb.Stateless;
@Stateless
public class Service {
public void upload(final Callback callback) {
callback.call();
}
}
/** Callback class */
public class Callback {
public void call() {
System.out.println(this + " called.");
}
}
/** Trigger class */
import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
@Singleton
public class Trigger {
@EJB
Service service;
@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void triggerService() {
System.out.println("Trigger Service call");
service.upload(new Callback());
//or by JNDI lookup and method overriding
try {
Service serviceByLookup = (Service) InitialContext.doLookup("java:module/Service");
serviceByLookup.upload(new Callback() {
@Override
public void call() {
System.out.println("Overriden: " + super.toString());
}
});
} catch (final NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
也可以将Callback 类实现为StatelessBean 并将其注入Service 类。
/** Service class */
@Stateless
public class Service {
@EJB
Callback callback;
public void upload() {
callback.call();
}
}
案例 2:使用远程业务接口
如果您使用的是远程接口,则无法将回调对象传递给您的 EJB。要将状态信息返回给您的客户端,您必须使用 JMS。
下面是一个简短的启动示例。
@Remote
public interface IService {
void upload();
}
@Stateless
public class Service implements IService {
@EJB
private AsyncUploadStateSender uploadStateSender;
@Override
public void upload() {
for (int i = 0; i <= 100; i += 10) {
uploadStateSender.sendState(i);
try {
Thread.sleep(1000L);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Stateless
public class AsyncUploadStateSender {
@Resource(lookup = "jms/myQueue")
private Queue queue;
@Inject
private JMSContext jmsContext;
@Asynchronous
public void sendState(final int state) {
final JMSProducer producer = jmsContext.createProducer();
final TextMessage msg = jmsContext.createTextMessage("STATE CHANGED " + state + "%");
producer.send(queue, msg);
}
}
public class Client {
public static void main(final String args[]) throws NamingException, InterruptedException, JMSException {
final InitialContext ctx = ... // create the InitialContext;
final IService service = (IService) ctx.lookup("<JNDI NAME OF IService>");
final ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jms/__defaultConnectionFactory");
final Queue queue = (Queue) ctx.lookup("jms/myQueue");
// set consumer
final Connection connection = factory.createConnection();
final MessageConsumer consumer = connection.createSession().createConsumer(queue);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(final Message msg) {
try {
System.out.println(((TextMessage) msg).getText());
} catch (final JMSException e) {
e.printStackTrace();
}
}
});
connection.start();
// start upload
service.upload();
Thread.sleep(1000L);
}
}
注意:您必须在应用服务器中创建队列jms/myQueue 和连接工厂jms/__defaultConnectionFactory 才能使示例正常运行。