Java 中的动态、反射式 SignalHandler

发布于 2024-08-31 23:19:55 字数 519 浏览 8 评论 0原文

如果 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 类实例化另一个匿名内部类,但我认为这只是一厢情愿的语法。

How do I install signal handling logic iff sun.misc.Signal is available?

Background
First generation of my code, which assumed signal handling availability, looked something like this:

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

I believe I understand how to reflectively test for and use signal handlers -- Class.forName("sun.misc.Signal"), reflectively call Signal.handle, and so forth.

My impulse was simply to instantiate another anonymous inner class with the dynamically obtained SignalHandler class, but I think that's just wishful syntax.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温折酒 2024-09-07 23:19:55

您需要使用动态代理来实现 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);

You need to use a Dynamic Proxy to implement the SignalHandler interface. The rest is just basic reflection.

Update

Here's how you do it. Note, I've omitted the try-catch that needs to wrap all of this

        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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文