序
本文主要研究一下artemis对junit的支持
TestRule
junit-4.12-sources.jar!/org/junit/rules/TestRule.java
public interface TestRule {
/**
* Modifies the method-running {@link Statement} to implement this
* test-running rule.
*
* @param base The {@link Statement} to be modified
* @param description A {@link Description} of the test implemented in {@code base}
* @return a new statement, which may be the same as {@code base},
* a wrapper around {@code base}, or a completely new Statement.
*/
Statement apply(Statement base, Description description);
}
- TestRule定义了apply方法用于修改并返回Statement
ExternalResource
junit-4.12-sources.jar!/org/junit/rules/ExternalResource.java
public abstract class ExternalResource implements TestRule {
public Statement apply(Statement base, Description description) {
return statement(base);
}
private Statement statement(final Statement base) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
};
}
/**
* Override to set up your specific external resource.
*
* @throws Throwable if setup fails (which will disable {@code after}
*/
protected void before() throws Throwable {
// do nothing
}
/**
* Override to tear down your specific external resource.
*/
protected void after() {
// do nothing
}
}
- ExternalResource声明实现了TestRule接口,其apply方法创建一个匿名Statement并重写其evaluate方法,该方法先执行before,在执行base.evaluate(),最后执行after
EmbeddedActiveMQResource
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResource.java
public class EmbeddedActiveMQResource extends ExternalResource {
//......
/**
* Invoked by JUnit to setup the resource - start the embedded ActiveMQ Artemis server
*/
@Override
protected void before() throws Throwable {
log.info("Starting {}: {}", this.getClass().getSimpleName(), getServerName());
this.start();
super.before();
}
/**
* Invoked by JUnit to tear down the resource - stops the embedded ActiveMQ Artemis server
*/
@Override
protected void after() {
log.info("Stopping {}: {}", this.getClass().getSimpleName(), getServerName());
this.stop();
super.after();
}
public void start() {
try {
server.start();
} catch (Exception ex) {
throw new RuntimeException(String.format("Exception encountered starting %s: %s", server.getClass().getName(), this.getServerName()), ex);
}
configuration = server.getActiveMQServer().getConfiguration();
}
public void stop() {
if (internalClient != null) {
internalClient.stop();
internalClient = null;
}
if (server != null) {
try {
server.stop();
} catch (Exception ex) {
log.warn(String.format("Exception encountered stopping %s: %s", server.getClass().getSimpleName(), this.getServerName()), ex);
}
}
}
//......
}
- EmbeddedActiveMQResource继承了ExternalResource,并覆盖了before及after方法;before执行的是start方法,after执行的是stop方法;start方法主要是执行EmbeddedActiveMQ.start;stop方法主要是执行InternalClient.stop以及EmbeddedActiveMQ.stop
AbstractActiveMQClientResource
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/AbstractActiveMQClientResource.java
public abstract class AbstractActiveMQClientResource extends ExternalResource {
//......
@Override
protected void before() throws Throwable {
super.before();
start();
}
@Override
protected void after() {
stop();
super.after();
}
void start() {
log.info("Starting {}", this.getClass().getSimpleName());
try {
sessionFactory = serverLocator.createSessionFactory();
session = sessionFactory.createSession(username, password, false, true, true, serverLocator.isPreAcknowledge(), serverLocator.getAckBatchSize());
} catch (RuntimeException runtimeEx) {
throw runtimeEx;
} catch (Exception ex) {
throw new ActiveMQClientResourceException(String.format("%s initialisation failure", this.getClass().getSimpleName()), ex);
}
createClient();
try {
session.start();
} catch (ActiveMQException amqEx) {
throw new ActiveMQClientResourceException(String.format("%s startup failure", this.getClass().getSimpleName()), amqEx);
}
}
void stop() {
stopClient();
if (session != null) {
try {
session.close();
} catch (ActiveMQException amqEx) {
log.warn("ActiveMQException encountered closing InternalClient ClientSession - ignoring", amqEx);
} finally {
session = null;
}
}
if (sessionFactory != null) {
sessionFactory.close();
sessionFactory = null;
}
if (serverLocator != null) {
serverLocator.close();
serverLocator = null;
}
}
protected abstract void createClient();
protected abstract void stopClient();
//......
}
- AbstractActiveMQClientResource继承了ExternalResource,其before方法执行的是start方法,其after方法执行的是stop方法;start方法会创建session,执行createClient,最后执行session.start;stop方法执行stopClient、session.close、sessionFactory.close、serverLocator.close;它定义了createClient、stopClient抽象方法需要子类去实现
ActiveMQProducerResource
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQProducerResource.java
public class ActiveMQProducerResource extends AbstractActiveMQClientResource {
//......
@Override
protected void createClient() {
try {
if (!session.addressQuery(address).isExists() && autoCreateQueue) {
log.warn("{}: queue does not exist - creating queue: address = {}, name = {}", this.getClass().getSimpleName(), address.toString(), address.toString());
session.createQueue(address, address);
}
producer = session.createProducer(address);
} catch (ActiveMQException amqEx) {
throw new ActiveMQClientResourceException(String.format("Error creating producer for address %s", address.toString()), amqEx);
}
}
@Override
protected void stopClient() {
if (producer != null) {
try {
producer.close();
} catch (ActiveMQException amqEx) {
log.warn("ActiveMQException encountered closing InternalClient ClientProducer - ignoring", amqEx);
} finally {
producer = null;
}
}
}
//......
}
- ActiveMQProducerResource继承了AbstractActiveMQClientResource;其createClient方法执行session.createProducer(address);其stopClient方法执行producer.close()
ActiveMQConsumerResource
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
public class ActiveMQConsumerResource extends AbstractActiveMQClientResource {
//......
@Override
protected void createClient() {
boolean browseOnly = false;
try {
if (!session.queueQuery(queueName).isExists() && autoCreateQueue) {
log.warn("{}: queue does not exist - creating queue: address = {}, name = {}", this.getClass().getSimpleName(), queueName.toString(), queueName.toString());
session.createAddress(queueName, RoutingType.MULTICAST, true);
session.createQueue(queueName, queueName);
}
consumer = session.createConsumer(queueName, browseOnly);
} catch (ActiveMQException amqEx) {
throw new ActiveMQClientResourceException(String.format("Error creating consumer for queueName %s", queueName.toString()), amqEx);
}
}
@Override
protected void stopClient() {
if (consumer != null) {
try {
consumer.close();
} catch (ActiveMQException amqEx) {
log.warn("Exception encountered closing consumer - ignoring", amqEx);
} finally {
consumer = null;
}
}
}
//......
}
- ActiveMQConsumerResource继承了AbstractActiveMQClientResource,其createClient方法执行的是session.createConsumer(queueName, browseOnly);其stopClient方法执行的是consumer.close()
小结
artemis对junit的ExternalResource提供了扩展,对于server端提供了EmbeddedActiveMQResource,对于client端提供了AbstractActiveMQClientResource(ActiveMQProducerResource、ActiveMQConsumerResource
)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。