In Java, an annotation is a form of metadata that provides information to the compiler or runtime environment but does not directly affect program execution.
Common Java Annotations
Annotation | Purpose |
---|---|
@Override | Indicates a method is overriding a method from a superclass |
@Deprecated | Marks a method/class as deprecated (not recommended for use) |
@SuppressWarnings | Tells the compiler to suppress specific warnings |
@FunctionalInterface | Marks an interface as a functional interface (used in lambda expressions) |
@SafeVarargs | Suppresses warnings for varargs when used with generics |
@Resource
@Resource is part of Java’s standard (JSR-250), not Spring specifically — but Spring supports it fully for dependency injection.
@Resource is a Java EE annotation used to inject a dependency by name (not type by default).
import javax.annotation.Resource;
public class MyComponent {
@Resource
private MyService myService; // Injected by name
}
Key Characteristics of @Resource
Feature | Description |
---|---|
Source | Comes from JSR-250 (javax.annotation.Resource) |
Injection type | By name first, falls back to type if no match |
Works on | Fields and setter methods |
Spring support | Fully supported by Spring (like @Autowired) |
Comparison with @Autowired
Feature | @Resource | @Autowired |
---|---|---|
Injection type | By name, then by type fallback | By type |
Provided by | Java standard (JSR-250) | Spring Framework |
Nullable by default | No, throws exception if no match | Yes, unless @Autowired(required = false) |
Primary use case | Integration with standard Java EE APIs | Preferred in Spring-only projects |
Example: Field Injection
@Component
public class OrderService {
@Resource
private PaymentProcessor paymentProcessor;
// Spring will look for a bean named "paymentProcessor"
}
If there’s a bean named paymentProcessor, it gets injected. Otherwise, Spring looks for a bean of type PaymentProcessor. If multiple beans match and the name doesn’t resolve, you’ll get a NoUniqueBeanDefinitionException.
Tip: Use with Bean Naming
@Bean(name = "fastProcessor")
public PaymentProcessor fastPaymentProcessor() {
return new FastPaymentProcessor();
}
// or
@Resource(name = "fastProcessor")
private PaymentProcessor processor;
This works well when injecting by specific bean name.
✅ When to Use @Resource**
- When integrating with legacy or Java EE code
- When you want to inject by bean name deliberately
- In simple apps where you want clear, explicit injection behavior
But in modern Spring apps, it’s generally preferred to use:
- @Autowired (for injection by type)
- @Qualifier (to specify which bean when multiple candidates exist)
- @Constructor injection (best practice)
@value
What is @Value?
@Value is a Spring annotation used to inject values into fields, constructor arguments, or method parameters. These values can come from:
- application.properties or application.yml
- System environment variables
- Computed Spring Expression Language (SpEL)
- Other bean properties
Basic Usage
# application.properties
app.name=MyApp
app.timeout=30
@Component
public class MyService {
@Value("${app.name}")
private String appName;
@Value("${app.timeout}")
private int timeout;
}
Constructor Injection
@Component
public class ConfigService {
private final String appName;
public ConfigService(@Value("${app.name}") String appName) {
this.appName = appName;
}
}
Advanced Features
Use case | Example | Description |
---|---|---|
Default value | @Value("${app.port:8080}") | Use 8080 if app.port is not set |
System variable | @Value("${JAVA_HOME}") | Injects value from system env |
SpEL expression | @Value("#{2 * 60}") | Injects result of expression (120) |
Access bean field | @Value("#{myBean.property}") | Injects a value from another bean |
List injection | @Value("#{’${app.list}’.split(’,’)}") | Splits string into list/array |
Lombok
- @Data: Generates getters, setters, toString, equals, and hashCode.
- @Builder: Enables the builder pattern for object creation.
- @Slf4j: Adds a logger field (private static final Logger log = LoggerFactory.getLogger(…);).
@Data
@Data 是 Lombok 的复合注解,作用是:
- 自动为所有字段生成:
- getter / setter 方法
- equals() 和 hashCode() 方法(基于所有字段)
- toString() 方法
- 自动生成一个 全参构造方法(如果没有 @Builder 或手动定义构造器)
- 字段为 final 时不会生成 setter
适用于需要完整 POJO 功能的数据类。
@Builder
@Builder 为类提供 建造者模式(Builder Pattern):
- 自动生成一个静态内部类(Builder),允许链式调用设置字段。
- 自动生成 build() 方法,返回构造好的对象。
- 提供类型安全、可读性强的对象构造方式,适合字段多、参数可选性强的类。
适用于需要灵活构造对象的场景,避免多参数构造器出错。
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class User {
private String name;
private int age;
private String email;
}
// usage
User user = User.builder()
.name("Alice")
.age(30)
.email("alice@example.com")
.build();
// 生成的代码等价于
public class User {
private String name;
private int age;
private User(UserBuilder builder) {
this.name = builder.name;
this.age = builder.age;
}
// 静态 builder() 方法
public static UserBuilder builder() {
return new UserBuilder();
}
// 静态内部类
public static class UserBuilder {
private String name;
private int age;
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public User build() {
return new User(this);
}
}
// Getter 需手动加或用 @Getter/@Data
public String getName() { return name; }
public int getAge() { return age; }
}
@SuperBuilder
@SuperBuilder 是 Lombok 提供的注解,用于支持继承类之间的 Builder 模式。它是 @Builder 的增强版本,专门用于处理 父类 + 子类 的构造场景。
为什么需要 @SuperBuilder?
Lombok 的 @Builder 不支持继承结构(父类字段不会自动被子类 Builder 继承),而 @SuperBuilder 解决了这个问题。
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
class Parent {
private String parentField;
}
@Getter
@SuperBuilder
class Child extends Parent {
private String childField;
}
// usage
Child child = Child.builder()
.parentField("from parent")
.childField("from child")
.build();