Skip to content

Commit 4b19e71

Browse files
committed
静态代理&动态代理
1 parent c500618 commit 4b19e71

8 files changed

Lines changed: 297 additions & 4 deletions

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
* [使用Mockito作单元测试](src/cn/aofeng/demo/mockito)
4747

4848

49-
## 网络与I/O
49+
## 网络&I/O
5050
* [多线程网络echo服务](src/cn/aofeng/demo/io/MultiThreadEchoServer.java)
5151
* [线程池网络echo服务](src/cn/aofeng/demo/io/ThreadPoolEchoServer.java)
5252
* [NIO 缓冲区](src/cn/aofeng/demo/nio/BufferIO.java)
@@ -62,14 +62,14 @@
6262
### HTTP
6363
* [使用Fluent API发起HTTP请求(Get和Post)](src/cn/aofeng/demo/httpclient/FluentApi.java)
6464
* [使用HttpClient发起HTTP请求(Get, Post和上传文件)](src/cn/aofeng/demo/httpclient/FluentApi.java)
65-
* [使用JDK中的API建立简单的HTTP Server](src/cn/aofeng/demo/httpclient/SimpleHttpServer.java)
65+
* [使用JDK中的API建立简单的HTTP Server](src/cn/aofeng/demo/httpclient/server/SimpleHttpServer.java)
6666

6767
### Netty 4.0.x
6868
* [EchoServer](src/cn/aofeng/demo/netty40x/echo/EchoServer.java)
6969
* [EchoClient](src/cn/aofeng/demo/netty40x/echo/EchoClient.java)
7070

7171

72-
## 线程与并发
72+
## 线程&并发
7373
* [fork/join](src/cn/aofeng/demo/java/util/forkjoin/HelloForkJoin.java)
7474
* [Future](src/cn/aofeng/demo/java/util/future/HelloFuture.java)
7575
* [Future接口关系图](src/cn/aofeng/demo/java/util/future/Future.ucls)
@@ -78,11 +78,12 @@
7878
* [事件驱动的异步化框架:event4j](http://aofengblog.blog.163.com/blog/static/63170212014102463624267/)
7979
* [JDK HashMap源码分析 | HashMap Source Code Analysis](http://aofengblog.com/2014/08/14/JDK-HashMap%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/)
8080

81-
## 反射
81+
## 反射&代理
8282
* [获取构造方法、普通方法、字段和注解](src/cn/aofeng/demo/java/lang/reflect/ClassAnalyze.java)
8383
* [使用构造方法创建对象实例](src/cn/aofeng/demo/java/lang/reflect/CreateInstance.java)
8484
* [调用方法](src/cn/aofeng/demo/java/lang/reflect/InvokeMethod.java)
8585
* [获取/设置字段值](src/cn/aofeng/demo/java/lang/reflect/InvokeField.java)
86+
* [静态代理&动态代理](src/cn/aofeng/demo/proxy/AccountServiceClient.java)
8687

8788
## 脚本语言
8889
* [在Java中执行JavaScript脚本](src/cn/aofeng/demo/script/ScriptRunPerformence.java)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
/**
4+
* 账号服务接口定义。
5+
*
6+
* @author <a href="mailto:[email protected]">聂勇</a>
7+
*/
8+
public interface AccountService {
9+
10+
/**
11+
* 注册。
12+
*
13+
* @param username 账号名
14+
* @return 具体含义查看{@link Result}的说明。
15+
*/
16+
Result register(String username);
17+
18+
/**
19+
* 登录。
20+
*
21+
* @param username 账号名
22+
* @param password 密码
23+
* @return 具体含义查看{@link Result}的说明。
24+
*/
25+
Result login(String username, String password);
26+
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
/**
4+
* 代理调用示例。
5+
*
6+
* @author <a href="mailto:[email protected]">聂勇</a>
7+
*/
8+
public class AccountServiceClient {
9+
10+
public static void main(String[] args) {
11+
AccountService as = new AccountServiceImpl();
12+
13+
// 静态代理
14+
AccountService staticProxy = new AccountServiceStaticProxy(as);
15+
staticProxy.register(null);
16+
staticProxy.register("A0001");
17+
staticProxy.login(null, null);
18+
staticProxy.login("A0001", "PWD0001");
19+
20+
// 动态代理
21+
AccountService dynamicProxy = AccountServiceDynamicProxy.newInstance(as);
22+
dynamicProxy.register(null);
23+
dynamicProxy.register("A0001");
24+
dynamicProxy.login(null, null);
25+
dynamicProxy.login("A0001", "PWD0001");
26+
}
27+
28+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
import java.lang.reflect.InvocationHandler;
4+
import java.lang.reflect.Method;
5+
import java.lang.reflect.Proxy;
6+
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
/**
11+
* 账号服务动态代理。
12+
*
13+
* @author <a href="mailto:[email protected]">聂勇</a>
14+
*/
15+
public class AccountServiceDynamicProxy implements InvocationHandler {
16+
17+
private final static Logger _LOGGER = LoggerFactory.getLogger(AccountServiceDynamicProxy.class);
18+
19+
private AccountService _accountService;
20+
21+
public AccountServiceDynamicProxy(AccountService accountService) {
22+
this._accountService = accountService;
23+
}
24+
25+
@Override
26+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
27+
_LOGGER.debug("execute method {}, arguments: {}", method.getName(), args);
28+
Object result = method.invoke(_accountService, args);
29+
_LOGGER.debug("execute method {}, result:{}", method.getName(), result);
30+
31+
return result;
32+
}
33+
34+
public static AccountService newInstance(AccountService accountService) {
35+
ClassLoader loader = accountService.getClass().getClassLoader();
36+
Class<?>[] interfaces = accountService.getClass().getInterfaces();
37+
38+
return (AccountService) Proxy.newProxyInstance(loader,
39+
interfaces,
40+
new AccountServiceDynamicProxy(accountService));
41+
}
42+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
import java.util.Random;
4+
5+
import wiremock.org.apache.commons.lang.StringUtils;
6+
7+
/**
8+
*
9+
*
10+
* @author <a href="mailto:[email protected]">聂勇</a>
11+
*/
12+
public class AccountServiceImpl implements AccountService {
13+
14+
private final static Random NUM = new Random(System.currentTimeMillis());
15+
16+
@Override
17+
public Result register(String username) {
18+
if (StringUtils.isBlank(username)) {
19+
return createResult(4000001, "注册失败");
20+
}
21+
22+
User user = new User();
23+
user.setUid(NUM.nextInt());
24+
user.setNickname("用户"+user.getUid());
25+
return createResult(2000001, "注册成功", user);
26+
}
27+
28+
@Override
29+
public Result login(String username, String password) {
30+
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
31+
return createResult(4000001, "登录失败");
32+
}
33+
34+
User user = new User();
35+
user.setUid(NUM.nextInt());
36+
user.setNickname("用户"+user.getUid());
37+
return createResult(2000001, "登录成功", user);
38+
}
39+
40+
private Result createResult(int code, String msg) {
41+
Result result = new Result(code, msg);
42+
43+
return result;
44+
}
45+
46+
private Result createResult(int code, String msg, User user) {
47+
Result result = new Result(code, msg);
48+
result.setData(user);
49+
50+
return result;
51+
}
52+
53+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
/**
7+
* {@link AccountServiceImpl}的代理类,增加了输出入参和响应的日志。
8+
*
9+
* @author <a href="mailto:[email protected]">聂勇</a>
10+
*/
11+
public class AccountServiceStaticProxy implements AccountService {
12+
13+
private AccountService _delegate;
14+
15+
private final static Logger _LOGGER = LoggerFactory.getLogger(AccountServiceStaticProxy.class);
16+
17+
public AccountServiceStaticProxy(AccountService accountService) {
18+
this._delegate = accountService;
19+
}
20+
21+
@Override
22+
public Result register(String username) {
23+
_LOGGER.debug("execute method register, arguments: username={}", username);
24+
Result result = _delegate.register(username);
25+
_LOGGER.debug("execute method register, result:{}", result);
26+
27+
return result;
28+
}
29+
30+
@Override
31+
public Result login(String username, String password) {
32+
_LOGGER.debug("execute method login, arguments: username={}, password={}", username, password);
33+
Result result = _delegate.login(username, password);
34+
_LOGGER.debug("execute method login, result:{}", result);
35+
36+
return result;
37+
}
38+
39+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package cn.aofeng.demo.proxy;
2+
3+
/**
4+
* 账号服务操作结果。
5+
*
6+
* @author <a href="mailto:[email protected]">聂勇</a>
7+
*/
8+
public class Result {
9+
10+
/**
11+
* 200xxxx 表示成功。<br/>
12+
* 400xxxx 表示参数错误。<br/>
13+
* 500xxxx 表示服务内部错误。
14+
*/
15+
private int code;
16+
17+
/**
18+
* code对应的描述信息。
19+
*/
20+
private String msg;
21+
22+
/**
23+
* 只有code为200xxxx时才有值,其他情况下为null。
24+
*/
25+
private User data;
26+
27+
public Result() {
28+
// nothing
29+
}
30+
31+
public Result(int code, String msg) {
32+
this.code = code;
33+
this.msg = msg;
34+
}
35+
36+
public int getCode() {
37+
return code;
38+
}
39+
40+
public void setCode(int code) {
41+
this.code = code;
42+
}
43+
44+
public String getMsg() {
45+
return msg;
46+
}
47+
48+
public void setMsg(String msg) {
49+
this.msg = msg;
50+
}
51+
52+
public User getData() {
53+
return data;
54+
}
55+
56+
public void setData(User data) {
57+
this.data = data;
58+
}
59+
60+
@Override
61+
public String toString() {
62+
return "Result [code=" + code + ", msg=" + msg + ", data=" + data + "]";
63+
}
64+
65+
}

src/cn/aofeng/demo/proxy/User.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
*
3+
*/
4+
package cn.aofeng.demo.proxy;
5+
6+
/**
7+
* 用户信息。
8+
*
9+
* @author <a href="mailto:[email protected]">聂勇</a>
10+
*/
11+
public class User {
12+
13+
private long uid;
14+
15+
private String nickname;
16+
17+
public long getUid() {
18+
return uid;
19+
}
20+
21+
public void setUid(long uid) {
22+
this.uid = uid;
23+
}
24+
25+
public String getNickname() {
26+
return nickname;
27+
}
28+
29+
public void setNickname(String nickname) {
30+
this.nickname = nickname;
31+
}
32+
33+
@Override
34+
public String toString() {
35+
return "User [uid=" + uid + ", nickname=" + nickname + "]";
36+
}
37+
38+
}

0 commit comments

Comments
 (0)