1. Configuration Properties Binding over Scattered Injections@Value
What juniors often do:
@Value("${app.name}")
private String name;
@Value("${app.timeout}")
private int timeout;@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private int timeout;
// getters and setters
}# application.yml
app:
name: MyApp
timeout: 302. Constructor Injection over Field Injection
What juniors often do:
@Autowired
private OrderRepository orderRepository;What seniors do:
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
}
3. Using for Environment-Specific Beans@Profile
You wouldn’t hardcode your database password, right?
But what about behavior?
What juniors often do:
if (isProd) {
sendRealEmail();
} else {
logEmail();
}What seniors do:
@Profile("prod")
@Service
public class RealEmailService implements EmailService {
public void send(String msg) {
// actual logic
}
}
@Profile("dev")
@Service
public class MockEmailService implements EmailService {
public void send(String msg) {
log.info("Mock email: " + msg);
}
}spring:
profiles:
active: dev