温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么使用RelProxy提高Java开发效率

发布时间:2021-08-05 18:31:30 来源:亿速云 阅读:137 作者:chen 栏目:编程语言

本篇内容介绍了“怎么使用RelProxy提高Java开发效率”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

RelProxy 旨在通过下列两种方式提高开发效率:

可以在生产环境下修改用户代码,而不需要重新加载整个应用。

提高开发效率,避免花费过多的时间加载应用且对性能不会有影响。

两个目标都要求在你的应用中增加一些 RelProxy 代码,注册成一种典型的监听、回调模式。这是一种“侵入”的方式。

如果你是一名Java 框架或独立 Java 通用服务模块的开发者,可以将 RelProxy Java 嵌入到你的框架中,这样能透明地为框架的终端用户提供代码自动加载功能,只需要进行一些必要的配置,而无需调用 RelProxy API。

对使用 Java 版的 RelProxy,有两种 API 可供调用:

JProxy 及其相关类:主要是静态方法

Java 脚本 API:基于接口

第二种方式更适合将 RelProxy 嵌入到你的 Java 框架中,这种方式是基于接口的,在你的 API 中无需暴露公共 RelProxy  类,因为在框架中会执行启动程序。我将使用比较简单的 API:JProxyScriptEngineFactory.create()。

JProxyScriptEngine 的功能与 Jproxy 相同,也就是说具有相同的方法。只是这种情况下,只需要使用接口。

一个简单的例子是演示如何嵌入 RelProxy 的***方式。这个例子是 RelProxy 的示例仓库中包含的  RelProxyBuiltin(relproxy_builtin_ex  项目中)。它定义了两个监听器来实现注册用户端的代码,一个监听器显示选项(option),另一个执行选择的行为。

这个迷你框架和示例使用 NetBeans 和 Maven 开发完成。

有两个包:

com.innowhere.relproxy_builtin_ex :迷你框架。子包 com.innowhere.relproxy_builtin_ex.impl 只包含一个非公共的类。

com.innowhere.relproxy_builtin_ex_main :一个简单的使用示例。

迷你框架(公共类和接口):

RelProxyBuiltinRoot.java

1

2

3

4

5

6

7

8

9

10

package com.innowhere.relproxy_builtin_ex;

import com.innowhere.relproxy_builtin_ex.impl.RelProxyBuiltinImpl;

public class RelProxyBuiltinRoot

{

    private final static RelProxyBuiltinImpl SINGLETON = new RelProxyBuiltinImpl();

    public static RelProxyBuiltin get()

    {

        return SINGLETON;

    }

}

RelProxyBuiltin.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package com.innowhere.relproxy_builtin_ex;

import com.innowhere.relproxy.jproxy.JProxyScriptEngine;

import java.io.InputStream;

import java.io.PrintStream;

public interface RelProxyBuiltin

{

    public JProxyScriptEngine getJProxyScriptEngine();

    public void addOutputListener(OutputListener listener);

    public void removeOutputListener(OutputListener listener);

    public int getOutputListenerCount();

    public void addCommandListener(CommandListener listener);

    public void removeCommandListener(CommandListener listener);

    public int getCommandListenerCount();

    public void runLoop(InputStream in,PrintStream out);

}

OutputListener.java

1

2

3

4

5

6

package com.innowhere.relproxy_builtin_ex;

import java.io.PrintStream;

public interface OutputListener

{

    public void write(PrintStream out);

}

CommandListener.java

1

2

3

4

5

6

package com.innowhere.relproxy_builtin_ex;

import java.io.PrintStream;

public interface CommandListener

{

    public void execute(String command,String input,PrintStream out);

}

现在看一下实现细节,该类演示了怎样简单地内嵌 RelProxy:

RelProxyBuiltinImpl.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

package com.innowhere.relproxy_builtin_ex.impl;

import com.innowhere.relproxy.jproxy.JProxyScriptEngine;

import com.innowhere.relproxy.jproxy.JProxyScriptEngineFactory;

import com.innowhere.relproxy_builtin_ex.CommandListener;

import com.innowhere.relproxy_builtin_ex.OutputListener;

import com.innowhere.relproxy_builtin_ex.RelProxyBuiltin;

import java.io.InputStream;

import java.io.PrintStream;

import java.util.LinkedHashSet;

import java.util.Scanner;

public class RelProxyBuiltinImpl implements RelProxyBuiltin

{

    protected JProxyScriptEngine jProxyEngine = null;

    protected LinkedHashSet<OutputListener> outListeners = new LinkedHashSet<OutputListener>();

    protected LinkedHashSet<CommandListener>  commandListeners = new LinkedHashSet<CommandListener>();

    @Override

    public JProxyScriptEngine getJProxyScriptEngine()

    {

        if (jProxyEngine == null) jProxyEngine = (JProxyScriptEngine)JProxyScriptEngineFactory.create().getScriptEngine();

        return jProxyEngine;

    }

    public JProxyScriptEngine getJProxyScriptEngineIfConfigured()

    {

        if (jProxyEngine == null || !jProxyEngine.isEnabled())

            return null;

        return jProxyEngine;

    }

    @Override

    public void addOutputListener(OutputListener listener)

    {

        JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();

        if (jProxy != null)

        {

            listener = jProxy.create(listener,OutputListener.class);

        }

        outListeners.add(listener);

    }

    @Override

    public void removeOutputListener(OutputListener listener)

    {

        JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();

        if (jProxy != null)

        {

            listener = jProxy.create(listener,OutputListener.class);

        }

        outListeners.remove(listener);

    }

    @Override

    public int getOutputListenerCount()

    {

        return outListeners.size();

    }

    @Override

    public void addCommandListener(CommandListener listener)

    {

        JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();

        if (jProxy != null)

        {

            listener = jProxy.create(listener,CommandListener.class);

        }

        commandListeners.add(listener);

    }

    @Override

    public void removeCommandListener(CommandListener listener)

    {

        JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();

        if (jProxy != null)

        {

            listener = jProxy.create(listener,CommandListener.class);

        }

        commandListeners.remove(listener);

    }

    @Override

    public int getCommandListenerCount()

    {

        return commandListeners.size();

    }

    @Override

    public void runLoop(InputStream in,PrintStream out)

    {

        Scanner scanner = new Scanner(in);

        while(true)

        {

            out.print("Enter phrase:");

            String input = scanner.nextLine();

            out.println("Command list:");

            for(OutputListener listener : outListeners)

                listener.write(out);

            out.print("Enter command (or quit):");

            String command = scanner.nextLine();

            if ("quit".equals(command))

                break;

            for(CommandListener listener : commandListeners)

                listener.execute(command,input,out);

        }

    }

}

这三个方法足以解释怎样启动 RelProxy Java 引擎,怎样简单地使用指令监听器来注册热加载。

RelProxyBuiltinImpl.java (部分)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Override

  public JProxyScriptEngine getJProxyScriptEngine()

  {

      if (jProxyEngine == null) jProxyEngine = (JProxyScriptEngine)JProxyScriptEngineFactory.create().getScriptEngine();

      return jProxyEngine;

  }

  public JProxyScriptEngine getJProxyScriptEngineIfConfigured()

  {

      if (jProxyEngine == null || !jProxyEngine.isEnabled())

          return null;

      return jProxyEngine;

  }

  @Override

  public void addOutputListener(OutputListener listener)

  {

      JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();

      if (jProxy != null)

      {

          listener = jProxy.create(listener,OutputListener.class);

      }

      outListeners.add(listener);

  }

公共方法 RelProxyBuiltin.getJProxyScriptEngine() 必须在启动时执行,用于配置 RelProxy。如果没有配置,RelProxy 就不起作用。

请记住,通过 create(&hellip;) 创建的代理对象需要能正确的执行 hashCode() 方法和 equals(Object) 方法,监听器集合、监听记录依赖这两个方法来区别监听器对象。

这是基于控制台的示例代码(名称与 JUnit 类似,但确实不是 JUnit 的测试示例):

Main.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

package com.innowhere.relproxy_builtin_ex_main;

import com.innowhere.relproxy.RelProxyOnReloadListener;

import com.innowhere.relproxy.jproxy.JProxy;

import com.innowhere.relproxy.jproxy.JProxyCompilerListener;

import com.innowhere.relproxy.jproxy.JProxyConfig;

import com.innowhere.relproxy.jproxy.JProxyDiagnosticsListener;

import com.innowhere.relproxy.jproxy.JProxyInputSourceFileExcludedListener;

import com.innowhere.relproxy.jproxy.JProxyScriptEngine;

import com.innowhere.relproxy_builtin_ex.CommandListener;

import com.innowhere.relproxy_builtin_ex.RelProxyBuiltin;

import com.innowhere.relproxy_builtin_ex.RelProxyBuiltinRoot;

import java.io.File;

import java.lang.reflect.Method;

import java.net.URL;

import java.util.Arrays;

import java.util.List;

import javax.tools.Diagnostic;

import javax.tools.DiagnosticCollector;

import javax.tools.JavaFileObject;

public class Main

{

    public static void main(String[] args) throws Exception

    {

        new Main();

    }

    public Main()

    {

        // Note: NetBeans Console window works bad (no input) with Maven Test tasks http://stackoverflow.com/questions/3035351/broken-console-in-maven-project-using-netbeans

        // this is why is not a really JUnit test.

        setUp();

        try

        {

            mainTest();

        }

        finally

        {

            tearDown();

        }

        System.exit(0);

    }

    public void setUp()

    {

        URL res = this.getClass().getResource("/"); // .../target/classes/

        // Use example of RelProxy in development time:

        String inputPath = res.getFile() + "/../../src/main/java/";

        if (new File(inputPath).exists())

        {

            System.out.println("RelProxy to be enabled, development mode detected");

        }

        else

        {

            System.out.println("RelProxy disabled, production mode detected");

            return;

        }

        JProxyInputSourceFileExcludedListener excludedListener = new JProxyInputSourceFileExcludedListener()

        {

            @Override

            public boolean isExcluded(File file, File rootFolderOfSources)

            {

                String absPath = file.getAbsolutePath();

                if (file.isDirectory())

                {

                    return absPath.endsWith(File.separatorChar + "relproxy_builtin_ex");

                }

                else

                {

                    return absPath.endsWith(File.separatorChar + Main.class.getSimpleName() + ".java");

                }

            }

        };

        String classFolder = null; // Optional

        Iterable<String> compilationOptions = Arrays.asList(new String[]{"-source","1.6","-target","1.6"});

        long scanPeriod = 1000;

        RelProxyOnReloadListener proxyListener = new RelProxyOnReloadListener() {

            @Override

            public void onReload(Object objOld, Object objNew, Object proxy, Method method, Object[] args) {

                System.out.println("Reloaded " + objNew + " Calling method: " + method);

            }

        };

        JProxyCompilerListener compilerListener = new JProxyCompilerListener(){

            @Override

            public void beforeCompile(File file)

            {

                System.out.println("Before compile: " + file);

            }

            @Override

            public void afterCompile(File file)

            {

                System.out.println("After compile: " + file);

            }

        };

        JProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener()

        {

            @Override

            public void onDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics)

            {

                List<Diagnostic<? extends JavaFileObject>> diagList = diagnostics.getDiagnostics();

                int i = 1;

                for (Diagnostic diagnostic : diagList)

                {

                   System.err.println("Diagnostic " + i);

                   System.err.println("  code: " + diagnostic.getCode());

                   System.err.println("  kind: " + diagnostic.getKind());

                   System.err.println("  line number: " + diagnostic.getLineNumber());

                   System.err.println("  column number: " + diagnostic.getColumnNumber());

                   System.err.println("  start position: " + diagnostic.getStartPosition());

                   System.err.println("  position: " + diagnostic.getPosition());

                   System.err.println("  end position: " + diagnostic.getEndPosition());

                   System.err.println("  source: " + diagnostic.getSource());

                   System.err.println("  message: " + diagnostic.getMessage(null));

                   i++;

                }

            }

        };

        RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();

        JProxyScriptEngine engine = rpbRoot.getJProxyScriptEngine();

        JProxyConfig jpConfig = JProxy.createJProxyConfig();

        jpConfig.setEnabled(true)

                .setRelProxyOnReloadListener(proxyListener)

                .setInputPath(inputPath)

                .setJProxyInputSourceFileExcludedListener(excludedListener)

                .setScanPeriod(scanPeriod)

                .setClassFolder(classFolder)

                .setCompilationOptions(compilationOptions)

                .setJProxyCompilerListener(compilerListener)

                .setJProxyDiagnosticsListener(diagnosticsListener);

        engine.init(jpConfig);

        System.out.println("RelProxy running");

    }

    public void tearDown()

    {

        RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();

        JProxyScriptEngine engine = rpbRoot.getJProxyScriptEngine();

        engine.stop();

        System.out.println("RelProxy stopped");

    }

    public void mainTest()

    {

        RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();

        TestListener listener = new TestListener();

        rpbRoot.addOutputListener(listener);

        assertTrue(rpbRoot.getOutputListenerCount() == 1);

        rpbRoot.removeOutputListener(listener);

        assertTrue(rpbRoot.getOutputListenerCount() == 0);

        rpbRoot.addOutputListener(listener);

        CommandListener commandListener = listener.getCommandListener();

        rpbRoot.addCommandListener(commandListener);

        assertTrue(rpbRoot.getCommandListenerCount() == 1);

        rpbRoot.removeCommandListener(commandListener);

        assertTrue(rpbRoot.getCommandListenerCount() == 0);

        rpbRoot.addCommandListener(commandListener);

        rpbRoot.runLoop(System.in,System.out);

    }

    private static void assertTrue(boolean res)

    {

        if (!res) throw new RuntimeException("Unexpected Error");

    }

}

看一下这段代码:

Main.java (部分)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

URL res = this.getClass().getResource("/"); // .../target/classes/

       // Use example of RelProxy in development time:

       String inputPath = res.getFile() + "/../../src/main/java/";

       if (new File(inputPath).exists())

       {

           System.out.println("RelProxy to be enabled, development mode detected");

       }

       else

       {

           System.out.println("RelProxy disabled, production mode detected");

           return;

       }

       JProxyInputSourceFileExcludedListener excludedListener = new JProxyInputSourceFileExcludedListener()

       {

           @Override

           public boolean isExcluded(File file, File rootFolderOfSources)

           {

               String absPath = file.getAbsolutePath();

               if (file.isDirectory())

               {

                   return absPath.endsWith(File.separatorChar + "relproxy_builtin_ex");

               }

               else

               {

                   return absPath.endsWith(File.separatorChar + Main.class.getSimpleName() + ".java");

               }

           }

       };

我们获取并注册应用源代码的根目录,该代码“可能”会被重新加载。

我们需要排除框架代码,因为这显然不是用户的代码(不需要重新加载)。此外,还需要排除 Main.java  文件,该文件包含了测试代码,也不需要重新加载,只有 TestListener.java 类(与 Main.java  在同一文件夹下)需要(必需)重新加载。

*** TestListener.java 类包含两个监听器,CommandListener 的实现采用匿名内部类的方式,主要目的是为了演示。

TestListener.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

package com.innowhere.relproxy_builtin_ex_main;

import com.innowhere.relproxy_builtin_ex.CommandListener;

import com.innowhere.relproxy_builtin_ex.OutputListener;

import java.io.PrintStream;

public class TestListener implements OutputListener

{

    @Override

    public void write(PrintStream out)

    {

        out.println("uppercase");

        out.println("lowercase");

    }

    public CommandListener getCommandListener()

    {

        return new CommandListener()

        {

            @Override

            public void execute(String command,String text,PrintStream out)

            {

                if ("uppercase".equals(command))

                    out.println(text.toUpperCase());

                else if ("lowercase".equals(command))

                    out.println(text.toLowerCase());

                else

                    out.println("Unknown command:" + command);

            }

        };

    }

}

先预定义可选项,然后执行 Main 类。为了校验 RelProxy 是否起作用,可以在不停止程序的运行的基础上增加一个新的可选项“same”。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

@Override

    public void write(PrintStream out)

    {

        out.println("uppercase");

        out.println("lowercase");

        out.println("same");  // NEW

    }

    public CommandListener getCommandListener()

    {

        return new CommandListener()

        {

            @Override

            public void execute(String command,String text,PrintStream out)

            {

                if ("uppercase".equals(command))

                    out.println(text.toUpperCase());

                else if ("lowercase".equals(command))

                    out.println(text.toLowerCase());

                else if ("same".equals(command)) // NEW

                    out.println(text); // NEW

                else

                    out.println("Unknown command:" + command);

            }

        };

    }

}

“怎么使用RelProxy提高Java开发效率”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI