0
# Dependency Injection and Lifecycle Management
1
2
Complete annotation-based dependency injection system with lifecycle callback support for enterprise Java applications. Handles @Resource, @PostConstruct, and @PreDestroy annotations with full webapp context integration.
3
4
## Capabilities
5
6
### Resource Injection
7
8
Performs dependency injection of JNDI resources into object fields and methods, supporting both field and method injection patterns with complete type safety.
9
10
```java { .api }
11
class Injection {
12
// Field injection constructor
13
Injection(Class<?> clazz, Field field, Class<?> resourceType, String jndiName, String mappingName);
14
15
// Method injection constructor
16
Injection(Class<?> clazz, Method method, Class<?> arg, Class<?> resourceType, String jndiName, String mappingName);
17
18
// Generic target injection constructor
19
Injection(Class<?> clazz, String target, Class<?> resourceType, String jndiName, String mappingName);
20
21
// Perform injection into target object
22
void inject(Object injectable);
23
24
// Lookup the resource value from JNDI
25
Object lookupInjectedValue() throws NamingException;
26
27
// Query methods
28
Class<?> getTargetClass();
29
Class<?> getParamClass();
30
Class<?> getResourceClass();
31
String getJndiName();
32
String getMappingName();
33
boolean isField();
34
boolean isMethod();
35
Member getTarget();
36
}
37
```
38
39
**Usage Example:**
40
```java
41
// Field injection setup
42
Field dataSourceField = MyClass.class.getDeclaredField("dataSource");
43
Injection injection = new Injection(
44
MyClass.class,
45
dataSourceField,
46
DataSource.class,
47
"jdbc/MyDB",
48
"mappedName"
49
);
50
51
// Inject into an instance
52
MyClass instance = new MyClass();
53
injection.inject(instance);
54
```
55
56
### Injection Collection Management
57
58
Manages collections of injections per class, providing centralized coordination of dependency injection across webapp contexts with thread-safe read operations.
59
60
```java { .api }
61
class InjectionCollection {
62
// Constants
63
static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
64
65
// Add injection to collection
66
void add(Injection injection);
67
68
// Retrieve injections for specific class
69
Set<Injection> getInjections(String className);
70
71
// Get specific field injection
72
Injection getInjection(String jndiName, Class<?> clazz, Field field);
73
74
// Get specific method injection
75
Injection getInjection(String jndiName, Class<?> clazz, Method method, Class<?> paramClass);
76
77
// Inject all applicable injections into object
78
void inject(Object injectable);
79
}
80
```
81
82
**Usage Example:**
83
```java
84
// Set up injection collection in webapp context
85
WebAppContext webapp = new WebAppContext();
86
InjectionCollection injections = new InjectionCollection();
87
webapp.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
88
89
// Add injections for various classes
90
injections.add(dataSourceInjection);
91
injections.add(envEntryInjection);
92
93
// Inject into any compatible object
94
Object serviceInstance = new MyService();
95
injections.inject(serviceInstance);
96
```
97
98
### Lifecycle Callback Management
99
100
Manages PostConstruct and PreDestroy lifecycle callbacks with validation and execution coordination for enterprise application lifecycle management.
101
102
```java { .api }
103
abstract class LifeCycleCallback {
104
// Constants
105
static final Object[] __EMPTY_ARGS = new Object[]{};
106
107
// Constructors
108
LifeCycleCallback(String className, String methodName);
109
LifeCycleCallback(Class<?> clazz, String methodName);
110
111
// Execute the callback
112
void callback(Object instance) throws SecurityException, NoSuchMethodException,
113
ClassNotFoundException, IllegalArgumentException, IllegalAccessException,
114
InvocationTargetException;
115
116
// Validate callback method constraints
117
abstract void validate(Class<?> clazz, Method m);
118
119
// Query methods
120
Class<?> getTargetClass();
121
String getTargetClassName();
122
String getMethodName();
123
Method getTarget();
124
125
// Utility method for finding methods
126
Method findMethod(Package pack, Class<?> clazz, String methodName, boolean checkInheritance);
127
}
128
129
class LifeCycleCallbackCollection {
130
// Constants
131
static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
132
133
// Add callback to collection
134
void add(LifeCycleCallback callback);
135
136
// Execute PostConstruct callbacks
137
void callPostConstructCallback(Object o) throws Exception;
138
139
// Execute PreDestroy callbacks
140
void callPreDestroyCallback(Object o) throws Exception;
141
142
// Get callbacks for specific object
143
Set<LifeCycleCallback> getPostConstructCallbacks(Object o);
144
Set<LifeCycleCallback> getPreDestroyCallbacks(Object o);
145
146
// Get all callbacks
147
Collection<LifeCycleCallback> getPostConstructCallbacks();
148
Collection<LifeCycleCallback> getPreDestroyCallbacks();
149
150
// Read-only views
151
Map<String, Set<LifeCycleCallback>> getPostConstructCallbackMap();
152
Map<String, Set<LifeCycleCallback>> getPreDestroyCallbackMap();
153
}
154
```
155
156
### PostConstruct Callbacks
157
158
Handles @PostConstruct annotation callbacks with proper validation of method constraints including parameter restrictions and access modifiers.
159
160
```java { .api }
161
class PostConstructCallback extends LifeCycleCallback {
162
// Constructors
163
PostConstructCallback(Class<?> clazz, String methodName);
164
PostConstructCallback(String className, String methodName);
165
166
// Validate PostConstruct method constraints
167
void validate(Class<?> clazz, Method method);
168
169
// Execute PostConstruct callback
170
void callback(Object instance);
171
}
172
```
173
174
**Usage Example:**
175
```java
176
// Set up PostConstruct callback
177
PostConstructCallback callback = new PostConstructCallback(MyService.class, "initialize");
178
179
// Add to collection
180
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
181
callbacks.add(callback);
182
183
// Execute on object creation
184
MyService service = new MyService();
185
callbacks.callPostConstructCallback(service);
186
```
187
188
### PreDestroy Callbacks
189
190
Handles @PreDestroy annotation callbacks with exception-safe execution and proper cleanup coordination for resource management.
191
192
```java { .api }
193
class PreDestroyCallback extends LifeCycleCallback {
194
// Constructors
195
PreDestroyCallback(Class<?> clazz, String methodName);
196
PreDestroyCallback(String className, String methodName);
197
198
// Validate PreDestroy method constraints
199
void validate(Class<?> clazz, Method method);
200
201
// Execute PreDestroy callback (exception-safe)
202
void callback(Object instance);
203
}
204
```
205
206
**Usage Example:**
207
```java
208
// Set up PreDestroy callback
209
PreDestroyCallback callback = new PreDestroyCallback(MyService.class, "cleanup");
210
211
// Add to collection
212
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
213
callbacks.add(callback);
214
215
// Execute during object destruction
216
callbacks.callPreDestroyCallback(service);
217
```
218
219
## Integration Patterns
220
221
### Complete Webapp Setup
222
223
```java
224
// Set up comprehensive annotation support in webapp
225
WebAppContext webapp = new WebAppContext();
226
227
// Configure injection collection
228
InjectionCollection injections = new InjectionCollection();
229
webapp.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
230
231
// Configure lifecycle callbacks
232
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
233
webapp.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
234
235
// Add field injection for DataSource
236
Field dsField = MyService.class.getDeclaredField("dataSource");
237
Injection dsInjection = new Injection(MyService.class, dsField, DataSource.class, "jdbc/MyDB", null);
238
injections.add(dsInjection);
239
240
// Add lifecycle callbacks
241
PostConstructCallback initCallback = new PostConstructCallback(MyService.class, "init");
242
PreDestroyCallback cleanupCallback = new PreDestroyCallback(MyService.class, "destroy");
243
callbacks.add(initCallback);
244
callbacks.add(cleanupCallback);
245
246
// Process service instance
247
MyService service = new MyService();
248
injections.inject(service); // Inject dependencies
249
callbacks.callPostConstructCallback(service); // Call @PostConstruct
250
251
// Later, during cleanup
252
callbacks.callPreDestroyCallback(service); // Call @PreDestroy
253
```
254
255
### Programmatic Injection Discovery
256
257
```java
258
// Discover and process injections for a class
259
InjectionCollection injections = (InjectionCollection)
260
webapp.getAttribute(InjectionCollection.INJECTION_COLLECTION);
261
262
// Get all injections for a specific class
263
Set<Injection> classInjections = injections.getInjections("com.example.MyService");
264
265
// Process each injection
266
for (Injection injection : classInjections) {
267
if (injection.isField()) {
268
System.out.println("Field injection: " + injection.getTarget());
269
} else if (injection.isMethod()) {
270
System.out.println("Method injection: " + injection.getTarget());
271
}
272
273
// Get the resource that will be injected
274
Object resource = injection.lookupInjectedValue();
275
System.out.println("Resource type: " + resource.getClass());
276
}
277
```
278
279
## Thread Safety and Performance
280
281
- **InjectionCollection**: Read-safe with concurrent modifications, not safe for concurrent writes
282
- **LifeCycleCallbackCollection**: Read-safe with concurrent modifications, not safe for concurrent writes
283
- **Individual Injections**: Thread-safe for injection operations once configured
284
- **Callbacks**: Thread-safe for execution once configured
285
286
For optimal performance in multi-threaded environments, configure all injections and callbacks during application startup before concurrent access begins.