JBoss MSC API

Overview

JBoss MSC API 由三个部分组成:

  • Injector 接口
  • Value 接口
  • Service 接口

本文按顺序从这三个方面介绍 JBoss MSC API。

Injector 接口

org.jboss.msc.inject.Injector is a receiver for values that are injected from another source, typically connected to a service lifecycle. 它定义了两个方法:

  • inject(T value) throws InjectionException - Inject the given value.
  • uninject() - Uninject the given value (in other words, cancel or undo a previous injection). Only called after inject() has been called.

Injector 接口类图

MSC Inject

Injector 接口示例

示例.1 AtomicReferenceInjector inject value to `java.util.concurrent.atomic.AtomicReference`

final AtomicReference<String> reference = new AtomicReference<String>();
final Injector<String> injector = new AtomicReferenceInjector<String>(reference);
injector.inject("Hello World");
System.out.println(reference.get());
injector.uninject();

运行如上代码 Console 端输出 String Hello World

示例.2 FieldInjector inject value to POJO class's file.

SimplePojo 有 public Field description 如下:

public class SimplePojo {

	public String description;
}

如下代码演示 FieldInjector inject value to `description`:

final Field field = SimplePojo.class.getField("description");
final SimplePojo pojo = new SimplePojo();
final Injector<String> injector = new FieldInjector<String>(Values.immediateValue(pojo), field);
injector.inject("Injection of description field");
System.out.println(pojo.description);
injector.uninject();

运行如上代码 Console 端输出 String Injection of description field

示例.3 MethodInjector invokes a method

SimplePojo 有 public Method testMethod:

public void testMethod(String value) {
	System.out.println(value);
}

如下代码演示 MethodInjector invoke testMethod:

Value<SimplePojo> target = new ImmediateValue<>(new SimplePojo());
List<Value<String>> arguments =new ArrayList<>();
arguments.add(new ImmediateValue<String>("Hello World"));
final Injector<String> injector = new MethodInjector<String>(SimplePojo.class.getMethod("testMethod", String.class), target, Values.immediateValue("String"), arguments);
injector.inject(null);

运行如上代码 Console 端输出 String Hello World.

示例.4 SetMethodInjector call setter method

SimplePojo 有 public Method setId:

private Integer id;

public Integer getId() {
	return id;
}

public void setId(Integer id) {
	this.id = id;
}

如下代码演示 SetMethodInjector call setId:

Value<SimplePojo> target = new ImmediateValue<>(new SimplePojo());
Method method = SimplePojo.class.getMethod("setId", Integer.class);
final Injector<Integer> injector = SetMethodInjector.<Integer>create(target, method);
injector.inject(1000);
System.out.println(target.getValue().getId());
injector.uninject();

运行如上代码 Console 端输出 Integer 1000.

示例.5 CastingInjector casts the value to a specific type

SimplePojo 有 public Field listField:

public List<String> listField;

如下代码演示 CastingInjector casts the value to a specific type:

final Field field = SimplePojo.class.getField("listField");
List<String> list = new ArrayList<>();
SimplePojo pojo = new SimplePojo();
list.add("Hello World");
final Injector<List> fieldInjector = new FieldInjector<>(Values.immediateValue(pojo), field);
final Injector<Object> castingInjector = Injectors.cast(fieldInjector, List.class);
castingInjector.inject(list);
System.out.println(pojo.listField.get(0));
castingInjector.uninject();

运行如上代码 Console 端输出 String Hello World.

Value 接口

org.jboss.msc.value.Value is an ndirect value. A value may be available trivially (without any computation), or it may involve a complex calculation to produce. The value may also be time-sensitive, such that it is only available under certain circumstances (e.g. when the corresponding service is “up”).

Value 接口类图

MSC Value

Value 接口示例

示例.1 CachedValue

运行

Value<String> value = new CachedValue<>(new ImmediateValue<>("Hello World"));
System.out.println(value.getValue());

输出 Hello World

示例.2 CheckedValue

运行

Value<String> value = new CheckedValue<>(String.class, new ImmediateValue<>("Hello World"));
System.out.println(value.getValue());

输出 Hello World

示例.3 ClassOfValue

运行

Value<Class<? extends String>> value = new ClassOfValue<>(new ImmediateValue<>(""));
System.out.println(value.getValue());

输出 class java.lang.String

示例.4 ListItemValue

运行

List<String> list = new ArrayList<String>();
list.add("Hello World");
Value<String> value = new ListItemValue<>(new ImmediateValue<List<? extends String>>(list), new ImmediateValue<>(0));
System.out.println(value.getValue());

输出 Hello World

示例.5 ConstructedValue

如下代码

Constructor<SimplePojo> constructor = SimplePojo.class.getConstructor(new Class[]{});
Value<SimplePojo> value = new ConstructedValue<>(constructor, Collections.emptyList());
System.out.println(value.getValue());

construct a SimplePojo Object.

示例.6 EnvironmentPropertyValue

运行

Value<String> value = new EnvironmentPropertyValue("PATH");
System.out.println(value.getValue());

输出系统参数 PATH 对应的值

示例.7 FieldValue

运行

SimplePojo pojo = new SimplePojo();
pojo.description = "Hello World";
Field field = SimplePojo.class.getField("description");
FieldValue<Integer> value = new FieldValue<Integer>(field, new ImmediateValue<>(pojo));
System.out.println(value.getValue());

输出 Hello World

示例.8 SystemPropertyValue

运行

Value<String> value = new SystemPropertyValue("user.home");
System.out.println(value.getValue());

输出当前用户目录

Service 接口

Service

A service is a thing which can be started and stopped. A service may be started or stopped from any thread. In general, injections will always happen from the same thread that will call start() method, and uninjections will always happen from the same thread that had called stop() method. However no other guarantees are made with respect to locking or thread safety; a robust service implementation should always take care to protect any mutable state appropriately.

The value type specified by this service is used by default by consumers of this service, and should represent the public interface of this service, which may or may not be the same as the implementing type of this service.

MSC Service

When writing MSC service implementations, start() and stop() methods must never block. This means these methods must not:

  • Use network connections
  • Wait for network connections
  • Sleep
  • Wait on a condition
  • Wait on a count down latch
  • Call any method which may do any of the above
  • Wait for termination of a thread pool or other service
  • Wait for another service to change state

If your service start/stop does any of these things, you must use the asynchronous start/stop mechanism LifecycleContext#asynchronous() and do one of the following:

  • Initiate your task in start()/stop(), and utilize a callback (NIO, ThreadPoolExecutor.terminated(), etc.) to call LifecycleContext#complete() when your start/stop completes instead of blocking.
  • Delegate your blocking task to a thread pool which calls LifecycleContext#complete() when done.
  • Use proper dependencies instead of explicitly waiting for services in your start/stop.

Note that using LifecycleContext#execute(Runnable) to execute the blocking task is also not permissible.

ServiceContainer

A Service usually reference with a ServiceController

MSC ServiceController

Use the controller we can get a service’s parent service, associated service container, service controller’s current mode, service state, etc.

A ServiceContainer used to manages a set of running services.

ServiceContainer

ServiceContainer 接口类图如下

MSC ServiceContainer

  • ServiceContainer - ServiceContainer 即是 JBoss MSC 的抽象,它抽象的是一个模块化的容器,它设计用来管理一系列服务
  • ServiceTarget - 提供了添加服务,添加依赖等方法,另外这些添加只有在ServiceBuilder 的 install() 方法后才生效
  • ServiceRegistry - 服务注册接口,可根据服务名获取一个服务,或获取所有服务名列表

另外,ServiceContainer 包含一个工厂类,用来创建 ServiceContainer,工厂类中 create() 方法如下:

public static ServiceContainer create()  
public static ServiceContainer create(String name)  
public static ServiceContainer create(int coreSize, long keepAliveTime, TimeUnit keepAliveTimeUnit)  
public static ServiceContainer create(String name, int coreSize, long keepAliveTime, TimeUnit keepAliveTimeUnit)  
public static ServiceContainer create(boolean autoShutdown)  
public static ServiceContainer create(String name, boolean autoShutdown)  
public static ServiceContainer create(int coreSize, long keepAliveTime, TimeUnit keepAliveTimeUnit, boolean autoShutdown)  
public static ServiceContainer create(String name, int coreSize, long keepAliveTime, TimeUnit keepAliveTimeUnit, boolean autoShutdown)

ContainerExecutor

ContainerExecutor 接口类图如下

MSC ThreadPool

ServiceContainer 接口的实现类 ServiceContainerImpl 中有一个 ContainerExecutor 属性,其中在实例化 ServiceContainerImpl 时 ContainerExecutor 被初始化,ContainerExecutor 实现了 ThreadPoolExecutor。