java如何实现BIO远程调用设置实例源码介绍?本文是使用BIO的方式实现远程调用,也就是是Server端基于ServerSocket和InpuStream,OutputStream;客户端是基于Socket和InputStream,OutputStream。
首先看看远程调用的接口和实现,因为是基于JDK动态代理机制,所以必须要有接口,个人建议使用接口的编程模式,如果是因为客观原因没有接口,那也可以使用CGLIB,不过缺点是final无法处理。
先上传代码,有空再详细说明实现的细节。
接口
1
2
3
4
5
6
|
@ImplClass (className = "org.tigerl.bio.HelloWorldImpl" ) public interface HelloWorld { public String getHelloWorld(String helloWorld); } |
实现类
1
2
3
4
5
6
7
8
9
10
11
|
public class HelloWorldImpl implements HelloWorld { private static int INDEX = 0 ; @Override public String getHelloWorld(String helloWorld) { String str = helloWorld + (INDEX++); return str; } } |
注解类
1
2
3
4
5
6
7
|
@Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) public @interface ImplClass { String className() default "" ; } |
客户端
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
|
public class SimpleClient { private Socket socket; private final BlockingQueue< byte []> inputBlockingQueue = new ArrayBlockingQueue<>( 100 ); private final BlockingQueue< byte []> outputBlockingQueue = new ArrayBlockingQueue<>( 100 ); public SimpleClient(String host, int port) throws UnknownHostException, IOException { socket = new Socket(host, port); } public static SimpleClient connectServer() throws UnknownHostException, IOException { final SimpleClient client = new SimpleClient( "localhost" , 7788 ); new Thread( new Runnable() { public void run() { try { client.start(); } catch (Exception e) { e.printStackTrace(); } } }).start(); return client; } public void start() throws InterruptedException, IOException { while ( true ) { byte [] bytes = inputBlockingQueue.take(); DataOutputStream output = new DataOutputStream(socket.getOutputStream()); output.writeInt(bytes.length); output.write(bytes); DataInputStream in = new DataInputStream(socket.getInputStream()); byte [] inBytes = new byte [in.readInt()]; in.read(inBytes); outputBlockingQueue.put(inBytes); } } public void stop() throws IOException { socket.close(); } public void putMessage(String message) throws InterruptedException, UnsupportedEncodingException { byte [] bytes = message.getBytes( "UTF-8" ); putBytes(bytes); } public void putBytes( byte [] bytes) throws InterruptedException { inputBlockingQueue.put(bytes); } public byte [] takeBytes() throws InterruptedException { return outputBlockingQueue.take(); } } |
客户端动态代理
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
|
public class ClientInvoking implements InvocationHandler { private String className; @SuppressWarnings ( "unchecked" ) public <T> T bing(Class<T> class_) { className = class_.getName(); Class<?>[] interfaces = new Class<?>[] {class_}; return (T) Proxy.newProxyInstance(class_.getClassLoader(), interfaces, this ); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { SimpleClient client = SimpleClient.connectServer(); ClassInfo classInfo = new ClassInfo(); classInfo.setClassName(className); classInfo.setMethodName(method.getName()); classInfo.setParameters(args); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(classInfo); byte [] bytes = bos.toByteArray(); client.putBytes(bytes); byte [] inBytes = client.takeBytes(); ObjectInputStream objIn = new ObjectInputStream( new ByteArrayInputStream(inBytes)); Object returnObj = objIn.readObject(); client.stop(); return returnObj; } } |
调用信息
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
|
public class ClassInfo implements Serializable { /** * */ private static final long serialVersionUID = 8971418367592789207L; private String className; private String methodName; private Object[] parameters; public String getClassName() { return className; } public void setClassName(String className) { this .className = className; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this .methodName = methodName; } public Object[] getParameters() { return parameters; } public void setParameters(Object[] parameters) { this .parameters = parameters; } } |
服务端代码
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
|
public class SimpleServer { private ServerSocket serverScoket; private ExecutorService executorService; public SimpleServer( int port) throws IOException { serverScoket = new ServerSocket(port); executorService = Executors.newFixedThreadPool( 10 ); } public void start() throws IOException { while ( true ) { Socket socket = serverScoket.accept(); executorService.execute( new WorkThread(socket)); } } private static class WorkThread implements Runnable { private Socket socket; private WorkThread(Socket socket) { this .socket = socket; } public void run() { try { DataInputStream in = new DataInputStream(socket.getInputStream()); int length = in.readInt(); byte [] bytes = new byte [length]; in.read(bytes); ObjectInputStream objIn = new ObjectInputStream( new ByteArrayInputStream(bytes)); ClassInfo classInfo = (ClassInfo)objIn.readObject(); Class<?> interfaceClass = Class.forName(classInfo.getClassName()); Class<?> implClass = Class.forName(interfaceClass.getAnnotation(ImplClass. class ).className()); Object obtj = implClass.newInstance(); Object[] objs = classInfo.getParameters(); Class<?>[] classes = new Class<?>[objs.length]; for ( int i = 0 ; i < objs.length; i++) { classes[i] = objs[i].getClass(); } Object returnObj = implClass.getDeclaredMethod(classInfo.getMethodName(), classes).invoke(obtj, objs); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream objOut = new ObjectOutputStream(byteOut); objOut.writeObject(returnObj); byte [] outBytes = byteOut.toByteArray(); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.writeInt(outBytes.length); out.write(outBytes); } catch (Exception e) { e.printStackTrace(); } } } } |
测试用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class BIOTest { @Test public void testSimpleServer() throws IOException { SimpleServer server = new SimpleServer( 7788 ); server.start(); } @Test public void testInvoking() throws UnknownHostException, IOException, InterruptedException { ClientInvoking clientInvoking = new ClientInvoking(); HelloWorld helloWorld = clientInvoking.bing(HelloWorld. class ); System.out.println(helloWorld.getHelloWorld( "test" )); } } |
本文固定链接: