Динамический, отражающий SignalHandler в Java - PullRequest
2 голосов
/ 06 мая 2010

Как установить логику обработки сигналов, если доступно sun.misc.Signal?

Фон Первое поколение моего кода, которое предполагало доступность обработки сигналов, выглядело примерно так:

class MyApp {
    public static void main(String[] args) {
        ...
        Signal.handle(term_sig, new SignalHandler() {
            public void handle(Signal sig) { ... }
        });
        ...
    }
}

Мне кажется, я понимаю, как рефлексивно проверять и использовать обработчики сигналов - Class.forName("sun.misc.Signal"), рефлексивно вызывать Signal.handle и т. Д.

Моим импульсом было просто создать другой анонимный внутренний класс с динамически полученным классом SignalHandler, но я думаю, что это просто желательный синтаксис.

1 Ответ

3 голосов
/ 07 мая 2010

Для реализации интерфейса SignalHandler необходимо использовать Динамический прокси . Все остальное - просто базовое отражение.

Обновление

Вот как ты это делаешь. Обратите внимание, я пропустил try-catch, который должен обернуть все это

        Class<?> handlerCl = Class.forName("sun.misc.SignalHandler");
        Class<?> signalCl = Class.forName("sun.misc.Signal");

        Constructor signalCtor = signalCl.getConstructor(String.class);
        Method signalHandle = signalCl.getMethod("handle", signalCl, handlerCl);

        // Create a proxy class that implements SignalHandler
        Class<?> proxyClass = Proxy.getProxyClass(signalCl.getClassLoader(),
            handlerCl);

        // This is used by the instance of proxyClass to dispatch method calls
        InvocationHandler invHandler = new InvocationHandler()
        {
            public Object invoke(Object proxy,
                Method method, Object[] args) throws Throwable
            {
                // proxy is the SignalHandler's "this" rederence
                // method will be the handle(Signal) method
                // args[0] will be an instance of Signal
                // If you're using this object for multiple signals, you'll
                // you'll need to use the "getName" method to determine which
                // signal you have caught.
                return null;
            }
        };

        // Get the constructor and create an instance of proxyClass
        Constructor<?> proxyCtor = proxyClass.getConstructor(InvocationHandler.class);
        Object handler = proxyCtor.newInstance(invHandler);

        // Create the signal and call Signal.handle to bind handler to signal
        Object signal = signalCtor.newInstance("TERM");
        signalHandle.invoke(null, signal, handler);
...