0
# Bean Style Support
1
2
Annotations for generating bean-style accessors and applying conservative coding conventions for enterprise environments. These annotations help integrate Immutables with frameworks that expect JavaBean conventions.
3
4
## Capabilities
5
6
### Bean-Style Accessors
7
8
Generate bean-style accessor methods with `get` and `is` prefixes.
9
10
```java { .api }
11
/**
12
* Generate bean-style accessor naming with get/is prefixes.
13
* Transforms accessor methods to follow JavaBean conventions
14
* for compatibility with frameworks expecting bean-style naming.
15
*/
16
@Target({ElementType.TYPE, ElementType.PACKAGE})
17
@Retention(RetentionPolicy.SOURCE)
18
@interface BeanStyle.Accessors {}
19
```
20
21
**Usage Example:**
22
23
```java
24
import org.immutables.value.Value;
25
import org.immutables.value.BeanStyle;
26
import java.util.List;
27
28
@Value.Immutable
29
@BeanStyle.Accessors
30
public interface Person {
31
String getName(); // Already bean-style
32
int getAge(); // Already bean-style
33
boolean isActive(); // Already bean-style
34
List<String> getTags(); // Already bean-style
35
}
36
37
// Generated implementation has bean-style accessors
38
Person person = ImmutablePerson.builder()
39
.name("Alice") // Builder uses simple names
40
.age(30)
41
.active(true)
42
.addTags("developer", "java")
43
.build();
44
45
// Accessors follow bean conventions
46
String name = person.getName();
47
int age = person.getAge();
48
boolean active = person.isActive();
49
List<String> tags = person.getTags();
50
```
51
52
### Conservative Bean Style
53
54
Apply conservative bean-style conventions with private implementation and constructor-based builders.
55
56
```java { .api }
57
/**
58
* Apply conservative bean-style conventions.
59
* Combines bean-style accessors, setter-style initialization,
60
* private implementation visibility, and constructor-based builders
61
* for maximum enterprise framework compatibility.
62
*/
63
@Target({ElementType.TYPE, ElementType.PACKAGE})
64
@Retention(RetentionPolicy.SOURCE)
65
@interface BeanStyle.Conservative {}
66
```
67
68
**Usage Example:**
69
70
```java
71
import org.immutables.value.Value;
72
import org.immutables.value.BeanStyle;
73
import java.util.Optional;
74
75
@Value.Immutable
76
@BeanStyle.Conservative
77
public interface Employee {
78
String getName();
79
String getEmail();
80
String getDepartment();
81
boolean isActive();
82
Optional<String> getManagerId();
83
}
84
85
// Conservative style generates:
86
// - Bean-style accessors (getName(), getEmail(), etc.)
87
// - Setter-style builder methods (setName(), setEmail(), etc.)
88
// - Private implementation class
89
// - Constructor-based builder pattern
90
91
// Usage with conservative style
92
Employee employee = ImmutableEmployee.builder()
93
.setName("Alice Smith") // Setter-style builder
94
.setEmail("alice@company.com")
95
.setDepartment("Engineering")
96
.setActive(true)
97
.setManagerId("mgr123")
98
.build();
99
100
// Bean-style accessors
101
String name = employee.getName();
102
String email = employee.getEmail();
103
boolean active = employee.isActive();
104
```
105
106
## Generated Features
107
108
### Bean-Style Accessor Patterns
109
110
When `@BeanStyle.Accessors` is applied:
111
112
```java
113
// Original interface
114
@Value.Immutable
115
@BeanStyle.Accessors
116
public interface UserData {
117
String username(); // Becomes getUsername()
118
int score(); // Becomes getScore()
119
boolean verified(); // Becomes isVerified()
120
List<String> roles(); // Becomes getRoles()
121
}
122
123
// Generated implementation
124
public final class ImmutableUserData implements UserData {
125
public String getUsername() { ... }
126
public int getScore() { ... }
127
public boolean isVerified() { ... }
128
public List<String> getRoles() { ... }
129
}
130
```
131
132
### Conservative Style Features
133
134
When `@BeanStyle.Conservative` is applied, it combines multiple style settings:
135
136
```java
137
// Equivalent to:
138
@Value.Style(
139
get = {"get*", "is*"}, // Bean-style accessors
140
init = "set*", // Setter-style builder methods
141
visibility = ImplementationVisibility.PRIVATE, // Private implementation
142
typeBuilder = "*Builder" // Constructor-based builder
143
)
144
@Value.Immutable
145
public interface ConservativeType {
146
// ... methods
147
}
148
```
149
150
## Framework Integration Examples
151
152
### Spring Framework Integration
153
154
```java
155
@Value.Immutable
156
@BeanStyle.Conservative
157
@Component
158
public interface ApplicationConfig {
159
@Value("${app.name}")
160
String getName();
161
162
@Value("${app.version}")
163
String getVersion();
164
165
@Value("${app.debug:false}")
166
boolean isDebugEnabled();
167
168
@Value("${app.features}")
169
List<String> getEnabledFeatures();
170
}
171
172
// Spring can inject values using bean-style setters in builder
173
@Configuration
174
public class ConfigurationSetup {
175
@Bean
176
public ApplicationConfig appConfig(
177
@Value("${app.name}") String name,
178
@Value("${app.version}") String version,
179
@Value("${app.debug:false}") boolean debug,
180
@Value("${app.features}") List<String> features) {
181
182
return ImmutableApplicationConfig.builder()
183
.setName(name)
184
.setVersion(version)
185
.setDebugEnabled(debug)
186
.setEnabledFeatures(features)
187
.build();
188
}
189
}
190
```
191
192
### Jackson Bean Integration
193
194
```java
195
@Value.Immutable
196
@BeanStyle.Accessors
197
@Jackson.Mapped
198
@JsonIgnoreProperties(ignoreUnknown = true)
199
public interface ApiResponse {
200
@JsonProperty("response_code")
201
int getResponseCode();
202
203
@JsonProperty("message")
204
String getMessage();
205
206
@JsonProperty("success")
207
boolean isSuccess();
208
209
@JsonProperty("data")
210
Optional<Object> getData();
211
}
212
213
// Jackson recognizes bean-style accessors
214
ObjectMapper mapper = new ObjectMapper();
215
String json = "{'response_code':200,'message':'OK','success':true}";
216
ApiResponse response = mapper.readValue(json, ApiResponse.class);
217
```
218
219
### JPA/Hibernate Integration
220
221
```java
222
@Value.Immutable
223
@BeanStyle.Conservative
224
@Entity
225
@Table(name = "users")
226
public interface UserEntity {
227
@Id
228
@Column(name = "user_id")
229
String getId();
230
231
@Column(name = "username", nullable = false)
232
String getUsername();
233
234
@Column(name = "email", nullable = false)
235
String getEmail();
236
237
@Column(name = "active")
238
boolean isActive();
239
240
@OneToMany(mappedBy = "user")
241
List<Role> getRoles();
242
}
243
244
// Conservative style works with JPA frameworks that expect
245
// bean-style accessors and constructor patterns
246
```
247
248
## Package-Level Configuration
249
250
Apply bean styles to entire packages via `package-info.java`:
251
252
```java
253
// package-info.java
254
@BeanStyle.Conservative
255
package com.example.model;
256
257
import org.immutables.value.BeanStyle;
258
```
259
260
This applies conservative bean style to all immutable types in the package.
261
262
## Migration from JavaBeans
263
264
Bean-style annotations help migrate from traditional mutable JavaBeans:
265
266
```java
267
// Traditional JavaBean
268
public class LegacyUser {
269
private String name;
270
private int age;
271
private boolean active;
272
273
// Getters and setters...
274
public String getName() { return name; }
275
public void setName(String name) { this.name = name; }
276
// ... etc
277
}
278
279
// Immutable replacement
280
@Value.Immutable
281
@BeanStyle.Conservative
282
public interface User {
283
String getName();
284
int getAge();
285
boolean isActive();
286
}
287
288
// Usage maintains similar patterns
289
User user = ImmutableUser.builder()
290
.setName("Alice") // Similar to setName()
291
.setAge(30) // Similar to setAge()
292
.setActive(true) // Similar to setActive()
293
.build();
294
295
String name = user.getName(); // Same as JavaBean
296
```
297
298
## Performance Considerations
299
300
- **Bean-style accessors**: No performance overhead - only naming changes
301
- **Conservative style**: Slightly more method dispatch due to builder patterns
302
- **Framework compatibility**: Enables efficient integration with bean-expecting frameworks
303
- **Code generation**: Bean styles are compile-time transformations with no runtime cost