引言
EJB的定时服务(Timer Service) ,定时服务作在一段特定的时就按后执行某段程序,咱们应该都用过。咱们就直接介绍EJB3.0定时服务的开发过程。定时服务的开发过程与会话过程大致相同,但比会话Bean多了几个操作,那就是使用容器对象SessionContext创建定时器,并使用@Timeout注释生命定时器方法。
下面我们做一个每隔3秒除法一次时间的定时器,当定时时间除法次数超过5次的时候便终止定时器的执行。
上代码:
服务端目录:
pom.xml:
<span style="font-size:18px;"><?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>yjmyzz</groupId>
<artifactId>ejb-server-helloworld</artifactId>
<version>1.0</version>
<packaging>ejb</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<version.jboss.spec.javaee.6.0>3.0.2.Final</version.jboss.spec.javaee.6.0>
<version.ejb.plugin>2.3</version.ejb.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>${version.jboss.spec.javaee.6.0}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.javaee</groupId>
<artifactId>javaee</artifactId>
<version>6.0-alpha-1</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.annotation</groupId>
<artifactId>jboss-annotations-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>${version.jboss.maven.plugin}</version>
<configuration>
<filename>${project.build.finalName}.jar</filename>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>${version.ejb.plugin}</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
<generateClient>true</generateClient>
</configuration>
</plugin>
</plugins>
</build>
</project>
</span>
TimeBean.java:
<span style="font-size:18px;">package yjmyzz.ejb.server.helloworld;
import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
@Stateless
@Remote({ TimerBeanRemote.class })
public class TimerBean implements TimerBeanRemote {
private static int count = 0;
@Resource
private TimerService timerService;
public void scheduleTimer(long milliseconds) {
if (count == 0) {
count = 1;
timerService.createTimer(new Date(new Date().getTime()
+ milliseconds), milliseconds, "第一个定时器");
}
}
@Timeout
public void timeoutHandler(Timer timer) {
System.out.println("定时器事件发生,执行次数为:" + count);
if (count >= 5) {
timer.cancel();
count = 0;
} else {
count++;
}
}
}
</span>
TimerBeanRemote.java:
<span style="font-size:18px;">package yjmyzz.ejb.server.helloworld;
public interface TimerBeanRemote {
public void scheduleTimer(long milliseconds);
}
</span>
服务端代码写好了。
客户端代码:
pom.xml:
<span style="font-size:18px;"><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>yjmyzz</groupId>
<artifactId>ejb-client-helloworld</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>ejb-client-helloworld</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>yjmyzz</groupId>
<artifactId>ejb-server-helloworld</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
<version>1.0.1.Final</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<!-- <version>1.0.2.Final-redhat-2</version> -->
<version>1.0.2.Final</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss-ejb-client</artifactId>
<!-- <version>1.0.21.Final-redhat-1</version> -->
<version>1.0.21.Final</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss.xnio</groupId>
<artifactId>xnio-nio</artifactId>
<version>3.0.7.GA</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss.sasl</groupId>
<artifactId>jboss-sasl</artifactId>
<version>1.0.3.Final</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling-river</artifactId>
<version>1.3.16.GA</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
</span>
TimerClient.java:
<span style="font-size:18px;">package yjmyzz.ejb.client.helloworld;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import yjmyzz.ejb.server.helloworld.HelloWorldService;
import yjmyzz.ejb.server.helloworld.TimerBeanRemote;
public class TimerClient {
public static void main(String[] args) throws NamingException {
lookupRemoteBean().scheduleTimer((long)3000);
}
@SuppressWarnings("unchecked")
private static TimerBeanRemote lookupRemoteBean() throws NamingException {
@SuppressWarnings("rawtypes")
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
return (TimerBeanRemote) context
.lookup("ejb:/ejb-server-helloworld/TimerBean!"
+ TimerBeanRemote.class.getName());
}
}
</span>
jboss-ejb-client.properties:
<span style="font-size:18px;">#remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
#remote.connections=default
#remote.connection.default.host=192.168.21.241
#remote.connection.default.port = 4447
#remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
#remote.connection.default.username=admin
#remote.connection.default.password=!admin123
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
org.jboss.ejb.client.scoped.context=true
jboss.naming.client.ejb.context=true
Context.URL_PKG_PREFIXES=org.jboss.ejb.client.naming
javax.naming.Context.INITIAL_CONTEXT_FACTORY=org.jboss.naming.remote.client.InitialContextFactory
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connectionprovider.create.options.org.xnio.Options.SSL_STARTTLS=false
jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
remote.connections=one
remote.connection.one.host=localhost
remote.connection.one.port=4447
remote.connection.one.username=admin
remote.connection.one.password=!admin123</span>
调用的时候,大家就可以看一下service端的输出和client端的输出。
总结:
无论是EJB的拦截器还是定时服务都是通过委托和事件来实现的,就好比容器都是通过配置文件和反射来实现的一样。