By default db4o uses JdkReflector(Java) or NetReflector (.NET) as a GenericReflector delegate.
However, the programmer can instruct db4o to use a specially designed reflection implementation:
Java: Db4o.configure().reflectWith(reflector)
where reflector is one of the available reflectors or your own reflector implementation.
At present db4o comes with SelfReflector, which was designed for environments, which do not have built-in support for reflections (J2ME for example). In this implementation all the classes' information is stored in special registry. User classes should implement self_get and self_set methods to be registered individually and become "known" to SelfReflector.
Specific reflectors can be written for special usecases.
Let's look how to create a reflector. Remember that db4o relies on reflector to read the database, so errors in reflector may prevent your database from opening.
To keep things simple we will write a LoggingReflector, its only difference from standard reflector is that information about loaded classes is outputted to console. All reflectors used by db4o should implement com.db4o.reflect.Reflector interface.
01/* Copyright (C) 2004 - 2005 db4objects Inc. http://www.db4o.com */ 02
03
package com.db4odoc.reflections; 04
05
import com.db4o.reflect.ReflectArray; 06
import com.db4o.reflect.ReflectClass; 07
import com.db4o.reflect.Reflector; 08
import com.db4o.reflect.jdk.JdkClass; 09
10
public class LoggingReflector implements Reflector { 11
private ReflectArray _array; 12
13
private Reflector _parent; 14
15
public LoggingReflector() { 16
17
} 18
19
public ReflectArray array() { 20
if (_array == null) { 21
_array = new LoggingArray(_parent); 22
} 23
return _array; 24
} 25
26
public boolean constructorCallsSupported() { 27
return true; 28
} 29
30
public ReflectClass forClass(Class clazz) { 31
ReflectClass rc = new JdkClass(_parent, clazz); 32
System.out.println("forClass: " + clazz + " -> " 33
+ (rc == null ? "" : rc.getName())); 34
return rc; 35
} 36
37
public ReflectClass forName(String className) { 38
try { 39
Class clazz = Class.forName(className); 40
ReflectClass rc = forClass(clazz); 41
System.out.println("forName: " + className + " -> " 42
+ (rc == null ? "" : rc.getName())); 43
return rc; 44
} catch (ClassNotFoundException e) { 45
return null; 46
} 47
} 48
49
public ReflectClass forObject(Object a_object) { 50
if (a_object == null) { 51
return null; 52
} 53
ReflectClass rc = _parent.forClass(a_object.getClass()); 54
System.out.println("forObject:" + a_object + " -> " 55
+ (rc == null ? "" : rc.getName())); 56
return rc; 57
} 58
59
public boolean isCollection(ReflectClass claxx) { 60
return false; 61
} 62
63
public void setParent(Reflector reflector) { 64
_parent = reflector; 65
} 66
67
public Object deepClone(Object context) { 68
return new LoggingReflector(); 69
} 70
}
The output can help you to track all the loaded classes.
Reflection is a powerful tool, which plays a fundamental role in db4o. Understanding reflection will help you to understand the whole db4o functionality in detail.