0
# Proxy and Enhancement
1
2
Core proxy generation functionality for creating enhanced classes with method interception, callback support, and dynamic interface implementation. This is the heart of CGLib's dynamic proxy capabilities.
3
4
## Capabilities
5
6
### Enhancer
7
8
The primary class for creating enhanced/proxied subclasses with method interception capabilities.
9
10
```java { .api }
11
/**
12
* Primary class for creating enhanced/proxied subclasses
13
*/
14
public class Enhancer {
15
// Static factory methods for simple use cases
16
public static Object create(Class type, Callback callback);
17
public static Object create(Class superclass, Class[] interfaces, Callback callback);
18
public static Object create(Class superclass, Class[] interfaces,
19
CallbackFilter filter, Callback[] callbacks);
20
21
// Instance configuration methods
22
public void setSuperclass(Class superclass);
23
public void setInterfaces(Class[] interfaces);
24
public void setCallback(Callback callback);
25
public void setCallbacks(Callback[] callbacks);
26
public void setCallbackFilter(CallbackFilter filter);
27
public void setUseFactory(boolean useFactory);
28
public void setUseCache(boolean useCache);
29
30
// Generation methods
31
public Object create();
32
public Object create(Class[] argumentTypes, Object[] arguments);
33
public Class createClass();
34
35
// Utility methods
36
public static void getMethods(Class superclass, Class[] interfaces, List methods);
37
public static void registerCallbacks(Class generatedClass, Callback[] callbacks);
38
public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks);
39
}
40
```
41
42
**Usage Examples:**
43
44
```java
45
// Simple method interception
46
Enhancer enhancer = new Enhancer();
47
enhancer.setSuperclass(MyService.class);
48
enhancer.setCallback(new MethodInterceptor() {
49
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
50
long start = System.currentTimeMillis();
51
try {
52
return proxy.invokeSuper(obj, args);
53
} finally {
54
System.out.println(method.getName() + " took " + (System.currentTimeMillis() - start) + "ms");
55
}
56
}
57
});
58
MyService proxy = (MyService) enhancer.create();
59
60
// Multiple interfaces with constructor arguments
61
enhancer = new Enhancer();
62
enhancer.setSuperclass(DatabaseService.class);
63
enhancer.setInterfaces(new Class[]{Serializable.class, Auditable.class});
64
enhancer.setCallback(myInterceptor);
65
DatabaseService service = (DatabaseService) enhancer.create(
66
new Class[]{String.class},
67
new Object[]{"jdbc:mysql://localhost/db"}
68
);
69
70
// Multiple callbacks with filter
71
enhancer = new Enhancer();
72
enhancer.setSuperclass(BusinessObject.class);
73
enhancer.setCallbacks(new Callback[]{
74
methodInterceptor, // index 0
75
NoOp.INSTANCE, // index 1
76
fixedValue // index 2
77
});
78
enhancer.setCallbackFilter(new CallbackFilter() {
79
public int accept(Method method) {
80
if (method.getName().startsWith("get")) return 1; // NoOp
81
if (method.getName().equals("toString")) return 2; // FixedValue
82
return 0; // MethodInterceptor
83
}
84
});
85
BusinessObject obj = (BusinessObject) enhancer.create();
86
```
87
88
### Callback Interfaces
89
90
#### MethodInterceptor
91
92
Intercepts method calls with full control over invocation.
93
94
```java { .api }
95
/**
96
* Intercepts method calls with full control over invocation
97
*/
98
public interface MethodInterceptor extends Callback {
99
/**
100
* Intercept a method call
101
* @param obj The enhanced object
102
* @param method The intercepted Method
103
* @param args Method arguments
104
* @param proxy MethodProxy for invoking super method
105
* @return Method return value
106
* @throws Throwable Any exception
107
*/
108
Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable;
109
}
110
```
111
112
#### FixedValue
113
114
Returns a fixed value for all intercepted methods.
115
116
```java { .api }
117
/**
118
* Returns a fixed value for all intercepted methods
119
*/
120
public interface FixedValue extends Callback {
121
/**
122
* Return the fixed value
123
* @return The value to return for all method calls
124
* @throws Exception Any exception
125
*/
126
Object loadObject() throws Exception;
127
}
128
```
129
130
#### LazyLoader
131
132
Loads a delegate object on first access, then delegates all calls to it.
133
134
```java { .api }
135
/**
136
* Loads a delegate object on first access, then delegates all calls to it
137
*/
138
public interface LazyLoader extends Callback {
139
/**
140
* Load the delegate object (called only once)
141
* @return The delegate object
142
* @throws Exception Any exception
143
*/
144
Object loadObject() throws Exception;
145
}
146
```
147
148
#### Dispatcher
149
150
Loads a delegate object for each method call.
151
152
```java { .api }
153
/**
154
* Loads a delegate object for each method call
155
*/
156
public interface Dispatcher extends Callback {
157
/**
158
* Load the delegate object (called for every method invocation)
159
* @return The delegate object
160
* @throws Exception Any exception
161
*/
162
Object loadObject() throws Exception;
163
}
164
```
165
166
#### ProxyRefDispatcher
167
168
Like Dispatcher but provides reference to the proxy object.
169
170
```java { .api }
171
/**
172
* Like Dispatcher but provides reference to the proxy object
173
*/
174
public interface ProxyRefDispatcher extends Callback {
175
/**
176
* Load the delegate object with access to the proxy
177
* @param proxy The proxy object
178
* @return The delegate object
179
* @throws Exception Any exception
180
*/
181
Object loadObject(Object proxy) throws Exception;
182
}
183
```
184
185
#### NoOp
186
187
No-operation callback that allows method calls to proceed normally.
188
189
```java { .api }
190
/**
191
* No-operation callback - methods proceed normally
192
*/
193
public interface NoOp extends Callback {
194
// Marker interface - no methods
195
NoOp INSTANCE = new NoOp() {};
196
}
197
```
198
199
#### InvocationHandler
200
201
JDK-compatible invocation handler for interface proxies.
202
203
```java { .api }
204
/**
205
* JDK-compatible invocation handler for interface proxies
206
*/
207
public interface InvocationHandler extends Callback {
208
/**
209
* Invoke a method on the proxy
210
* @param proxy The proxy object
211
* @param method The method being invoked
212
* @param args Method arguments
213
* @return Method return value
214
* @throws Throwable Any exception
215
*/
216
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
217
}
218
```
219
220
### CallbackFilter
221
222
Determines which callback to use for each method.
223
224
```java { .api }
225
/**
226
* Determines which callback to use for each method
227
*/
228
public interface CallbackFilter {
229
/**
230
* Choose callback index for a method
231
* @param method The method being intercepted
232
* @return Index of callback to use
233
*/
234
int accept(Method method);
235
}
236
```
237
238
### MethodProxy
239
240
Provides faster method invocation alternative to reflection.
241
242
```java { .api }
243
/**
244
* Faster method invocation alternative to reflection
245
*/
246
public class MethodProxy {
247
/**
248
* Create a MethodProxy
249
* @param c1 The enhanced class
250
* @param c2 The original class
251
* @param desc Method descriptor
252
* @param name1 Generated method name
253
* @param name2 Super method name
254
* @return MethodProxy instance
255
*/
256
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2);
257
258
/**
259
* Invoke the original method on the object
260
* @param obj Target object
261
* @param args Method arguments
262
* @return Method return value
263
* @throws Throwable Any exception
264
*/
265
public Object invoke(Object obj, Object[] args) throws Throwable;
266
267
/**
268
* Invoke the super method (recommended for interceptors)
269
* @param obj Enhanced object
270
* @param args Method arguments
271
* @return Method return value
272
* @throws Throwable Any exception
273
*/
274
public Object invokeSuper(Object obj, Object[] args) throws Throwable;
275
276
/**
277
* Get method signature
278
* @return Method signature
279
*/
280
public Signature getSignature();
281
282
/**
283
* Get super method name
284
* @return Super method name
285
*/
286
public String getSuperName();
287
288
/**
289
* Get super method index
290
* @return Super method index
291
*/
292
public int getSuperIndex();
293
}
294
```
295
296
### Factory Interface
297
298
Interface implemented by enhanced objects for callback management.
299
300
```java { .api }
301
/**
302
* Interface for callback management on enhanced objects
303
*/
304
public interface Factory {
305
/**
306
* Create new instance with single callback
307
* @param callback The callback to use
308
* @return New enhanced instance
309
*/
310
Object newInstance(Callback callback);
311
312
/**
313
* Create new instance with multiple callbacks
314
* @param callbacks Array of callbacks
315
* @return New enhanced instance
316
*/
317
Object newInstance(Callback[] callbacks);
318
319
/**
320
* Create new instance with constructor arguments and callbacks
321
* @param types Constructor parameter types
322
* @param args Constructor arguments
323
* @param callbacks Array of callbacks
324
* @return New enhanced instance
325
*/
326
Object newInstance(Class[] types, Object[] args, Callback[] callbacks);
327
328
/**
329
* Get callback by index
330
* @param index Callback index
331
* @return The callback
332
*/
333
Callback getCallback(int index);
334
335
/**
336
* Set callback by index
337
* @param index Callback index
338
* @param callback The callback to set
339
*/
340
void setCallback(int index, Callback callback);
341
342
/**
343
* Set all callbacks
344
* @param callbacks Array of callbacks
345
*/
346
void setCallbacks(Callback[] callbacks);
347
348
/**
349
* Get all callbacks
350
* @return Array of callbacks
351
*/
352
Callback[] getCallbacks();
353
}
354
```
355
356
### Mixin
357
358
Creates objects that implement multiple interfaces by delegating to different objects.
359
360
```java { .api }
361
/**
362
* Creates objects implementing multiple interfaces via delegation
363
*/
364
public abstract class Mixin {
365
// Style constants
366
public static final int STYLE_INTERFACES = 0;
367
public static final int STYLE_BEANS = 1;
368
public static final int STYLE_EVERYTHING = 2;
369
370
/**
371
* Create mixin from delegate objects
372
* @param delegates Array of delegate objects
373
* @return Mixin instance
374
*/
375
public static Mixin create(Object[] delegates);
376
377
/**
378
* Create mixin with specific interfaces
379
* @param interfaces Interfaces to implement
380
* @param delegates Delegate objects
381
* @return Mixin instance
382
*/
383
public static Mixin create(Class[] interfaces, Object[] delegates);
384
385
/**
386
* Create new mixin instance with different delegates
387
* @param delegates New delegate objects
388
* @return New mixin instance
389
*/
390
public abstract Mixin newInstance(Object[] delegates);
391
}
392
```
393
394
**Usage Example:**
395
396
```java
397
// Create objects implementing multiple interfaces
398
interface Readable { String read(); }
399
interface Writable { void write(String data); }
400
401
class Reader implements Readable {
402
public String read() { return "data"; }
403
}
404
405
class Writer implements Writable {
406
public void write(String data) { System.out.println(data); }
407
}
408
409
// Create mixin implementing both interfaces
410
Mixin mixin = Mixin.create(new Object[]{new Reader(), new Writer()});
411
Object combined = mixin.newInstance(new Object[]{new Reader(), new Writer()});
412
413
// Use as either interface
414
Readable readable = (Readable) combined;
415
Writable writable = (Writable) combined;
416
readable.read();
417
writable.write("hello");
418
```
419
420
### Proxy
421
422
Drop-in replacement for JDK dynamic proxies with additional features.
423
424
```java { .api }
425
/**
426
* Drop-in replacement for JDK dynamic proxies
427
*/
428
public class Proxy {
429
/**
430
* Get proxy class for interfaces
431
* @param loader ClassLoader to use
432
* @param interfaces Interfaces to implement
433
* @return Proxy class
434
*/
435
public static Class getProxyClass(ClassLoader loader, Class[] interfaces);
436
437
/**
438
* Create proxy instance
439
* @param loader ClassLoader to use
440
* @param interfaces Interfaces to implement
441
* @param h InvocationHandler
442
* @return Proxy instance
443
*/
444
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h);
445
446
/**
447
* Check if class is a proxy class
448
* @param cl Class to check
449
* @return true if proxy class
450
*/
451
public static boolean isProxyClass(Class cl);
452
453
/**
454
* Get invocation handler from proxy
455
* @param proxy Proxy object
456
* @return InvocationHandler
457
*/
458
public static InvocationHandler getInvocationHandler(Object proxy);
459
}
460
```
461
462
### CallbackHelper
463
464
Abstract utility class for managing multiple callbacks.
465
466
```java { .api }
467
/**
468
* Abstract utility for managing multiple callbacks
469
*/
470
public abstract class CallbackHelper {
471
/**
472
* Constructor
473
* @param superclass Superclass for enhanced objects
474
* @param interfaces Interfaces to implement
475
*/
476
public CallbackHelper(Class superclass, Class[] interfaces);
477
478
/**
479
* Get callback for a specific method (implement this)
480
* @param method The method
481
* @return Callback for the method
482
*/
483
protected abstract Object getCallback(Method method);
484
485
/**
486
* Get all callbacks
487
* @return Array of callbacks
488
*/
489
public Callback[] getCallbacks();
490
491
/**
492
* Get callback filter
493
* @return CallbackFilter instance
494
*/
495
public CallbackFilter getFilter();
496
}
497
```
498
499
### InterfaceMaker
500
501
Creates new interfaces at runtime.
502
503
```java { .api }
504
/**
505
* Creates new interfaces at runtime
506
*/
507
public class InterfaceMaker {
508
/**
509
* Add method signature to interface
510
* @param signature Method signature
511
* @param exceptions Exception types
512
*/
513
public void add(Signature signature, Type[] exceptions);
514
515
/**
516
* Add method to interface
517
* @param method Method to add
518
*/
519
public void add(Method method);
520
521
/**
522
* Add all methods from a class
523
* @param clazz Class to copy methods from
524
*/
525
public void add(Class clazz);
526
527
/**
528
* Create the interface
529
* @return Interface class
530
*/
531
public Class create();
532
}
533
```
534
535
### Exception Types
536
537
```java { .api }
538
/**
539
* Exception for undeclared checked exceptions
540
*/
541
public class UndeclaredThrowableException extends RuntimeException {
542
/**
543
* Constructor
544
* @param t The wrapped exception
545
*/
546
public UndeclaredThrowableException(Throwable t);
547
548
/**
549
* Get the wrapped exception
550
* @return The undeclared throwable
551
*/
552
public Throwable getUndeclaredThrowable();
553
}
554
```