-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtest.txt
164 lines (153 loc) · 4.74 KB
/
test.txt
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
159
160
161
162
163
164
# cglib
## 简介
cglib基于`asm`字节码生成框架,可以动态地改造指定类的方法,是spring实现AOP的重要支持。与JDK的动态代理不同,cglib的代理类继承了被代理类,而不是实现被代理类的接口。
*注意:在字节码的生成和类的创建上,JDK的动态代理效率更高;在代理方法的执行效率上,由于采用了`FastClass`,所有cglib的效率更高。* 因为JDK的动态代理中代理类中的方法是通过反射调用的,而cglib为代理类创建了FastClass对象,只要知道方法索引就可以直接调用指定方法。
## 使用例子
### 需求
模拟对用户数据进行增删改时校验权限
### 工程环境
增加的字段
修改的字段
JDK:1.8.0_231
增加的字段
减少的字段
增加的字段
IDE:Spring Tool Suites4 for Eclipse
### 代理的主要步骤
创建`Enhancer`对象:`Enhancer`是cglib代理的对外窗口,以下都是调用这个类的方法
`setSuperclass(Class superclass)`:设置被代理的类
`setCallback(final Callback callback)`:设置被代理类如何增强,这个`Callback`对象需要我们创建实现类,实现的接口是`MethodInterceptor`(是`Callback`的子接口)
`create()`:获得代理类
其他增加字段
### 创建项目
项目类型Maven Project,打包方式jar
### 引入依赖
增加字段1
删除字段2
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.8</version>
</dependency>
增加字段2
删除字段1
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
增加字段1
<scope>test</scope>
</dependency>
增加字段1
### 编写MethodInterceptor实现类
首先实现MethodInterceptor对类的方法进行改造。即设置类的方法如何增强?
包路径:`cn.zzs.cglib`
无关的字段2
```java
public class PermissionCheckInterceptor implements MethodInterceptor {
//设置类应该如何增强?
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//设置需要拦截的方法
HashSet<String> set = new HashSet<String>(6);
set.add("save");
set.add("delete");
set.add("update");
//进行权限校验
if(method != null && set.contains(method.getName())) {
System.out.println("进行权限校验");
}
//再执行被代理类的方法,这个执行过程使用了FastClass,相比JDK的动态代理执行效率更高
Object obj2 = proxy.invokeSuper(obj, args);
return obj2;
}
}
```
### 编写被代理类
包路径:`cn.zzs.cglib`
```java
/**
* @ClassName: UserController
* @Description: 对用户进行操作的Controller
* @author: zzs
* @date: 2019年8月31日 下午4:24:13
*/
public class UserController {
public void save() {
System.out.println("增加用户");
}
public void delete() {
System.out.println("删除用户");
}
public void update() {
System.out.println("修改用户");
}
public void find() {
System.out.println("查找用户");
}
}
```
### 编写测试类
包路径:`test`下的`cn.zzs.cglib`
```java
/**
* @ClassName: CglibTest
* @Description: 测试cglib动态代理,模拟对用户操作前进行权限校验
* @author: zzs
* @date: 2019年8月31日 下午4:50:06
*/
public class CglibTest {
@Test
public void test01() {
//创建PermissionCheckInterceptor实现类对象
PermissionCheckInterceptor permissionCheckInterceptor = new PermissionCheckInterceptor();
//创建Enhancer对象,用于方法增强
Enhancer enhancer = new Enhancer();
//设置哪个类的方法需要增强?
enhancer.setSuperclass(UserController.class);
//设置方法如何增强?这里传入的是Callback对象-MethodInterceptor父类
enhancer.setCallback(permissionCheckInterceptor);
//获取代理类实例
UserController userController = (UserController) enhancer.create();
System.out.println(userController);
//测试增强后的结果
System.out.println("-------------");
userController.save();
System.out.println("-------------");
userController.delete();
System.out.println("-------------");
userController.update();
System.out.println("-------------");
userController.find();
}
}
```
### 运行结果
cn.zzs.cglib.UserController$$EnhancerByCGLIB$$e6f193aa@7bfcd12c
-------------
进行权限校验
增加用户
-------------
进行权限校验
删除用户
-------------
进行权限校验
修改用户
-------------
查找用户
增加的字段
### 运行结果
cn.zzs.cglib.UserController$$EnhancerByCGLIB$$e6f193aa@7bfcd12c
-------------
进行权限校验
增加用户
-------------
进行权限校验
删除用户
-------------
进行权限校验
修改用户
-------------
查找用户
减少的字段