0
# Core Annotations
1
2
Core Jakarta Annotations provide fundamental functionality for lifecycle management, resource injection, nullability constraints, code generation markers, and priority ordering. These annotations form the foundation for dependency injection and container-managed components.
3
4
## Capabilities
5
6
### Lifecycle Management
7
8
Annotations for controlling component initialization and cleanup phases.
9
10
#### @PostConstruct
11
12
Marks a method to be executed after dependency injection is completed. The method is called before the class is put into service.
13
14
```java { .api }
15
/**
16
* Marks a method for post-construction callback.
17
* The method is invoked after dependency injection is completed.
18
* Only one method per class can be annotated with PostConstruct.
19
*
20
* Method requirements:
21
* - void return type
22
* - no parameters (except InvocationContext for interceptors)
23
* - can be any access modifier (public, protected, package-private, private)
24
* - must not be static (except in application client)
25
* - should not be final
26
* - if method throws unchecked exception, class must not be put into service
27
*/
28
@Target(METHOD)
29
@Retention(RUNTIME)
30
public @interface PostConstruct {
31
}
32
```
33
34
**Usage Examples:**
35
36
```java
37
import jakarta.annotation.PostConstruct;
38
39
public class EmailService {
40
private ConnectionPool connectionPool;
41
42
@PostConstruct
43
public void initialize() {
44
connectionPool = new ConnectionPool();
45
connectionPool.start();
46
System.out.println("Email service initialized");
47
}
48
}
49
50
// Private method example
51
public class DatabaseService {
52
@PostConstruct
53
private void setupConnection() {
54
// Initialization logic
55
}
56
}
57
```
58
59
#### @PreDestroy
60
61
Marks a method to be executed before the instance is removed by the container. Typically used to release resources or perform cleanup.
62
63
```java { .api }
64
/**
65
* Marks a method for pre-destruction callback.
66
* The method is invoked before the instance is removed by the container.
67
* Used to release resources or perform cleanup.
68
*
69
* Method requirements:
70
* - void return type
71
* - no parameters (except InvocationContext for interceptors)
72
* - can be any access modifier (public, protected, package-private, private)
73
* - must not be static
74
* - should not be final
75
* - if method throws unchecked exception, it is ignored by container
76
*/
77
@Target(METHOD)
78
@Retention(RUNTIME)
79
public @interface PreDestroy {
80
}
81
```
82
83
**Usage Examples:**
84
85
```java
86
import jakarta.annotation.PreDestroy;
87
88
public class CacheService {
89
private CacheManager cacheManager;
90
91
@PreDestroy
92
public void cleanup() {
93
if (cacheManager != null) {
94
cacheManager.shutdown();
95
System.out.println("Cache service cleaned up");
96
}
97
}
98
}
99
```
100
101
### Resource Injection
102
103
Annotations for dependency injection and resource management.
104
105
#### @Resource
106
107
Marks a resource that is needed by the application. Can be applied to fields, methods, or classes for different injection patterns.
108
109
**Important**: Even though not marked @Inherited, deployment tools must examine all superclasses to discover all uses of this annotation, including on private fields and methods of superclasses.
110
111
```java { .api }
112
/**
113
* Marks a resource needed by the application.
114
* Can be used for field injection, setter injection, or class-level declaration.
115
*/
116
@Target({TYPE, FIELD, METHOD})
117
@Retention(RUNTIME)
118
@Repeatable(Resources.class)
119
public @interface Resource {
120
/**
121
* JNDI name of the resource. Default is field name or JavaBeans property name.
122
*/
123
String name() default "";
124
125
/**
126
* Resource reference lookup name (global JNDI names).
127
*/
128
String lookup() default "";
129
130
/**
131
* Java type of the resource.
132
*/
133
Class<?> type() default Object.class;
134
135
/**
136
* Authentication type for the resource connection.
137
*/
138
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
139
140
/**
141
* Whether the resource can be shared between components.
142
*/
143
boolean shareable() default true;
144
145
/**
146
* Product-specific name for resource mapping (not portable).
147
*/
148
String mappedName() default "";
149
150
/**
151
* Description of the resource.
152
*/
153
String description() default "";
154
155
/**
156
* Authentication type enumeration.
157
*/
158
public enum AuthenticationType {
159
CONTAINER, // Container manages authentication
160
APPLICATION // Application manages authentication
161
}
162
}
163
```
164
165
**Usage Examples:**
166
167
```java
168
import jakarta.annotation.Resource;
169
170
// Field injection
171
public class OrderService {
172
@Resource(name = "jdbc/OrderDB")
173
private DataSource dataSource;
174
175
@Resource
176
private EntityManager entityManager; // Uses field name
177
178
@Resource(lookup = "java:global/jms/OrderQueue")
179
private Queue orderQueue;
180
}
181
182
// Method injection
183
public class PaymentService {
184
private DataSource paymentDB;
185
186
@Resource(name = "jdbc/PaymentDB")
187
public void setPaymentDataSource(DataSource ds) {
188
this.paymentDB = ds;
189
}
190
}
191
192
// Class-level declaration
193
@Resource(name = "jdbc/AppDB", type = DataSource.class,
194
description = "Main application database")
195
public class Application {
196
}
197
```
198
199
#### @Resources
200
201
Container annotation for multiple @Resource declarations on a single class.
202
203
```java { .api }
204
/**
205
* Container for multiple @Resource annotations.
206
*/
207
@Target(TYPE)
208
@Retention(RUNTIME)
209
public @interface Resources {
210
/**
211
* Array of Resource annotations.
212
*/
213
Resource[] value();
214
}
215
```
216
217
**Usage Examples:**
218
219
```java
220
import jakarta.annotation.Resources;
221
import jakarta.annotation.Resource;
222
223
@Resources({
224
@Resource(name = "jdbc/UserDB", type = DataSource.class),
225
@Resource(name = "jms/NotificationQueue", type = Queue.class),
226
@Resource(name = "mail/Session", type = Session.class)
227
})
228
public class MultiResourceService {
229
}
230
```
231
232
### Nullability Constraints
233
234
Annotations for expressing nullability constraints in APIs.
235
236
#### @Nonnull
237
238
Indicates that an annotated element must not be null. For fields, the field must not be null after construction. For methods, applies to the return value.
239
240
```java { .api }
241
/**
242
* The annotated element must not be null.
243
* Annotated fields must not be null after construction has completed.
244
* When applied to a method, applies to the method return value.
245
*
246
* No @Target specified - can be applied to any program element.
247
*/
248
@Documented
249
@Retention(RUNTIME)
250
public @interface Nonnull {
251
}
252
```
253
254
#### @Nullable
255
256
Indicates that an annotated element could be null under some circumstances. Useful for overriding @Nonnull assumptions.
257
258
```java { .api }
259
/**
260
* The annotated element could be null under some circumstances.
261
* Useful mostly for overriding a @Nonnull annotation.
262
* When applied to a method, applies to the method return value.
263
*
264
* No @Target specified - can be applied to any program element.
265
*/
266
@Documented
267
@Retention(RUNTIME)
268
public @interface Nullable {
269
}
270
```
271
272
**Usage Examples:**
273
274
```java
275
import jakarta.annotation.Nonnull;
276
import jakarta.annotation.Nullable;
277
278
public class UserService {
279
280
@Nonnull
281
public User createUser(@Nonnull String name, @Nullable String email) {
282
// Method guarantees non-null return
283
// name parameter must not be null
284
// email parameter may be null
285
return new User(name, email);
286
}
287
288
@Nullable
289
public User findUser(String id) {
290
// Method may return null if user not found
291
return userRepository.findById(id);
292
}
293
}
294
```
295
296
### Code Generation
297
298
Annotations for marking generated code.
299
300
#### @Generated
301
302
Marks source code that has been generated by tools. Used to differentiate user-written code from generated code.
303
304
```java { .api }
305
/**
306
* Marks source code as generated by tools.
307
* Used to differentiate user-written code from generated code.
308
*/
309
@Documented
310
@Target({PACKAGE, TYPE, ANNOTATION_TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER})
311
@Retention(SOURCE)
312
public @interface Generated {
313
/**
314
* Name of the code generator (required).
315
* Recommended: fully qualified class name.
316
*/
317
String[] value();
318
319
/**
320
* Date when source was generated.
321
* ISO 8601 format (e.g., "2001-07-04T12:08:56.235-0700").
322
*/
323
String date() default "";
324
325
/**
326
* Comments from the code generator.
327
*/
328
String comments() default "";
329
}
330
```
331
332
**Usage Examples:**
333
334
```java
335
import jakarta.annotation.Generated;
336
337
@Generated(value = "com.example.MyGenerator",
338
date = "2023-12-01T10:30:00.000Z",
339
comments = "Generated from schema v2.1")
340
public class GeneratedEntity {
341
342
@Generated("com.example.PropertyGenerator")
343
private String generatedField;
344
345
@Generated(value = "com.example.MethodGenerator",
346
comments = "Auto-generated getter")
347
public String getGeneratedField() {
348
return generatedField;
349
}
350
}
351
```
352
353
### Priority Ordering
354
355
Annotation for specifying execution priority.
356
357
#### @Priority
358
359
Indicates the priority order in which program elements should be used. The effect is defined by other specifications (e.g., Jakarta Interceptors).
360
361
**Important**: Priority values should generally be non-negative, with negative values reserved for special meanings such as "undefined" or "not specified".
362
363
```java { .api }
364
/**
365
* Indicates priority order for program elements.
366
* Lower values indicate higher priority.
367
*/
368
@Documented
369
@Retention(RUNTIME)
370
public @interface Priority {
371
/**
372
* Priority value (should generally be non-negative).
373
* Lower values indicate higher priority.
374
*/
375
int value();
376
}
377
```
378
379
**Usage Examples:**
380
381
```java
382
import jakarta.annotation.Priority;
383
384
@Priority(100)
385
public class HighPriorityInterceptor {
386
// Will be executed before lower priority interceptors
387
}
388
389
@Priority(500)
390
public class LowPriorityInterceptor {
391
// Will be executed after higher priority interceptors
392
}
393
394
// Common priority constants (from Jakarta Interceptors specification)
395
@Priority(Interceptor.Priority.PLATFORM_BEFORE) // 0
396
public class PlatformInterceptor { }
397
398
@Priority(Interceptor.Priority.LIBRARY_BEFORE) // 1000
399
public class LibraryInterceptor { }
400
401
@Priority(Interceptor.Priority.APPLICATION) // 2000
402
public class ApplicationInterceptor { }
403
```