Spring Boot relies heavily on annotations to reduce boilerplate and make configuration more direct. In day-to-day development, a small set of annotations covers most common needs: registering components, wiring dependencies, handling web requests, binding configuration, starting the application, and dealing with concerns such as transactions or scheduled jobs.

What matters most is not memorizing every annotation, but understanding the role each one plays and how they work together.

Bean registration and component roles

Spring manages application objects as Beans, and several annotations exist to declare what kind of component a class is.

@Component

@Component is the general-purpose stereotype. It marks a regular class so that Spring can discover it during component scanning and register it as a Bean automatically.

It fits utility classes and other shared components that do not clearly belong to MVC, service, or persistence layers.

@Component
public class MyUtils {
    public void helperMethod() { /* ... */ }
}

@Controller and @RestController

These two are both used in the web layer, but they serve different response styles.

  • @Controller identifies a Spring MVC controller that typically returns a view name. If you want it to return raw data, it needs to be combined with @ResponseBody.
  @Controller
  public class ViewController {
    @GetMapping("/page")
    public String showPage(Model model) {
        model.addAttribute("data", "Hello");
        return "index"; // 返回视图名
    }
  }
  • @RestController combines @Controller and @ResponseBody, so return values are written directly to the response body, usually as JSON or XML.
  @RestController
  public class ApiController {
    @GetMapping("/api/data")
    public User getUser() {
        return new User("Alice", 28); // 自动序列化为 JSON
    }
  }

@Service and @Repository

These are specialized component annotations tied to common application layers.

  • @Service marks the service layer and is mainly used for business logic.
  @Service
  public class OrderService {
    public void processOrder() { /* 业务逻辑 */ }
  }
  • @Repository marks persistence-layer components and is often used together with frameworks such as MyBatis.
  @Repository
  public interface UserDao {
    @Select("SELECT * FROM user WHERE id=#{id}")
    User findById(Long id);
  }

@Configuration and @Bean

When automatic scanning is not enough, Spring also lets you define Beans explicitly.

  • @Configuration marks a configuration class and serves as a Java-based replacement for traditional XML configuration.
  • @Bean is used inside that configuration class to create and register a Bean manually.

This is especially useful when Bean creation requires custom initialization logic.

  @Configuration
  public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(); // 配置数据源 Bean
    }
  }

Dependency injection annotations

Once Beans are registered, they usually need to be injected into other components.

@Autowired

@Autowired is Spring’s core injection annotation. It injects a Bean by type.

@RestController
public class UserController {
    @Autowired
    private UserService userService; // 注入服务层 Bean
}

@Resource

@Resource comes from the JDK. By default, it injects by name, and you can also specify the Bean name explicitly through the name attribute.

@RestController
public class UserController {
    @Resource(name = "userService")
    private UserService userService; // 按名称注入
}

@Qualifier

When multiple Beans share the same type, @Autowired alone may not know which one to inject. @Qualifier resolves that ambiguity by naming the target Bean.

@Service
public class UserService { /* ... */ }

@Service("adminService")
public class AdminService implements UserService { /* ... */ }

@RestController
public class Controller {
    @Autowired
    @Qualifier("adminService")
    private UserService service; // 指定注入 adminService
}

Web annotations for request handling

Spring Boot web development depends on a few annotations for routing requests and binding request data.

Request mapping

  • @RequestMapping is the general mapping annotation and supports multiple HTTP methods.
  @RestController
  @RequestMapping("/api/v1/users")
  public class UserController {
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public User getById(@PathVariable Long id) { /* ... */ }
  }
  • @GetMapping and @PostMapping are shortcut annotations for GET and POST requests, making the code more concise.
  @GetMapping("/list")
  public List list() { /* ... */ }

Parameter binding

Spring also provides convenient annotations for extracting data from different parts of an HTTP request.

  • @RequestParam reads query parameters such as ?name=Alice.
  @GetMapping("/search")
  public String search(@RequestParam String keyword, @RequestParam int page = 1) { /* ... */ }
  • @PathVariable reads values embedded in the URL path, such as /user/{id}.
  @GetMapping("/user/{id}")
  public User getUser(@PathVariable Long id) { /* ... */ }
  • @RequestBody converts JSON data from the request body into an object.
  @PostMapping("/create")
  public void create(@RequestBody User user) { /* 接收 JSON 数据 */ }

Configuration and property binding

Spring Boot places strong emphasis on externalized configuration, and two annotations are commonly used to read those values.

@Value

@Value is suitable when you only need a single property from a configuration file such as application.properties.

@Component
public class AppConfig {
    @Value("${server.port}")
    private int port; // 注入端口号
}

@ConfigurationProperties

When several related configuration values belong together, @ConfigurationProperties is a better fit. It binds a group of properties, including more complex structures, to a Java class.

# application.yml
my:
  app:
    name: "SpringBootDemo"
    env: dev
@Component
@ConfigurationProperties(prefix = "my.app")
public class AppProperties {
    private String name;
    private String env;
    // getters and setters
}

Startup and application-level configuration

@SpringBootApplication

This is the annotation typically placed on the main application class. It is a composite annotation that combines three key capabilities:

  • @Configuration: declares a configuration class.
  • @EnableAutoConfiguration: turns on auto-configuration for pieces such as Tomcat and Spring MVC.
  • @ComponentScan: scans the package of the main class and its subpackages for components.
  @SpringBootApplication
  public class DemoApplication {
  public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
  }
  }

@EnableAutoConfiguration

Although @SpringBootApplication usually covers it, @EnableAutoConfiguration can also be used directly when you want more manual control, including excluding specific auto-configuration classes.

@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
public class AppConfig { /* 排除数据源自动配置 */ }

Other important annotations

@Transactional

@Transactional is used to declare database transactions. It supports options such as propagation behavior and isolation level, and can automatically roll back when exceptions occur.

@Service
public class OrderService {
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {
        // 数据库操作,异常时自动回滚
    }
}

@Scheduled

@Scheduled is used for scheduled tasks and supports cron expressions.

@Component
public class ScheduledTask {
    @Scheduled(cron = "0 0 0 * * MON-FRI") // 每周一到周五零点执行
    public void cleanLogs() {
        // 定时清理日志任务
    }
}

@Scope

@Scope defines the lifecycle scope of a Bean. The default is singleton, but it can be changed when a different instantiation model is required.

@Bean
@Scope("prototype") // 每次注入创建新实例
public MyBean prototypeBean() {
    return new MyBean();
}

What is worth focusing on in practice

Spring Boot annotations are built around the idea of convention over configuration, which is why they can significantly improve development efficiency.

In actual projects, a few combinations matter more than anything else:

  • For component management, understand the @Component family—such as @Controller, @Service, and @Repository—and when to use them instead of @Bean plus @Configuration.
  • For dependency injection, know the difference between @Autowired and @Resource, and use @Qualifier when multiple candidates exist.
  • For web development, be comfortable with request mappings like @RequestMapping and with request data binding through @RequestBody and @PathVariable.
  • For configuration management, choose @Value for isolated properties and @ConfigurationProperties for grouped settings.

In real development, IDE support makes it easy to look up annotation details when needed. The more important skill is understanding the responsibility of each annotation and the way different annotations are combined across layers.