← Назад к вопросам

Что такое @Component?

1.0 Junior🔥 211 комментариев
#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

@Component аннотация в Spring

Аннотация @Component — это основная аннотация в Spring Framework для обозначения класса как компонента, который должен быть управляем контейнером Spring. Когда Spring сканирует classpath, он находит классы с @Component и создаёт их экземпляры, управляя их жизненным циклом и внедряя зависимости.

Основное использование

import org.springframework.stereotype.Component;

@Component
public class UserService {
    public User findUserById(Long id) {
        // Логика поиска пользователя
        return new User(id);
    }
    
    public void saveUser(User user) {
        // Логика сохранения пользователя
    }
}

Spring автоматически:

  1. Создаст экземпляр класса
  2. Поместит его в контейнер (IoC контейнер)
  3. Сделает его доступным для внедрения в другие бины

Внедрение зависимостей

@Component
public class OrderService {
    private UserService userService;  // Зависимость
    
    @Autowired
    public OrderService(UserService userService) {
        this.userService = userService;  // Spring внедрит UserService
    }
    
    public void createOrder(Long userId) {
        User user = userService.findUserById(userId);
        // Логика создания заказа
    }
}

Spring сам разрешит зависимость UserService и передаст её конструктору.

Специализированные аннотации

@Component — это обобщённая аннотация, но для разных слоёв приложения есть специализированные варианты, которые наследуют её функциональность:

1. @Service — для бизнес-логики

import org.springframework.stereotype.Service;

@Service
public class UserService {
    private UserRepository userRepository;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User createUser(String name, String email) {
        User user = new User(name, email);
        return userRepository.save(user);
    }
}

2. @Repository — для доступа к данным

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }
    
    public User save(User user) {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getName(), user.getEmail());
        return user;
    }
}

3. @Controller — для REST контроллеров

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {
    private UserService userService;
    
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findUserById(id);
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user.getName(), user.getEmail());
    }
}

Именование бинов

По умолчанию, имя бина — это имя класса с маленькой первой буквой:

@Component
public class MyService {
    // Имя бина: "myService"
}

// Но можно задать кастомное имя
@Component("customName")
public class MyService {
    // Имя бина: "customName"
}

При внедрении можно ссылаться на конкретный бин по имени:

@Component
public class MyController {
    @Autowired(required = false)
    @Qualifier("customName")
    private MyService myService;
}

Component Scanning

Spring должен знать, где искать компоненты. Это настраивается в конфигурации:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.example.service", "com.example.controller"})
public class AppConfig {
    // Spring будет сканировать указанные пакеты
}

Или в Spring Boot проекте это делается автоматически для пакета основного класса.

Область видимости (Scope)

import org.springframework.context.annotation.Scope;

@Component
@Scope("singleton")  // По умолчанию
public class SingletonService {
    // Один экземпляр для всего приложения
}

@Component
@Scope("prototype")  // Новый экземпляр при каждом запросе
public class PrototypeService {
    // Новый экземпляр каждый раз
}

@Component
@Scope("request")  // Новый для каждого HTTP запроса
public class RequestService {
}

@Component
@Scope("session")  // Один на пользовательскую сессию
public class SessionService {
}

Методы инициализации и разрушения

@Component
public class ResourceService {
    private Resource resource;
    
    @PostConstruct
    public void init() {
        System.out.println("Service initialized");
        resource = new Resource();
        resource.open();
    }
    
    @PreDestroy
    public void cleanup() {
        System.out.println("Service destroyed");
        if (resource != null) {
            resource.close();
        }
    }
}

Условное создание бинов

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

@Component
@ConditionalOnProperty(
    name = "app.cache.enabled",
    havingValue = "true",
    matchIfMissing = false
)
public class CacheService {
    // Этот бин создастся только если app.cache.enabled = true
}

Профили

import org.springframework.context.annotation.Profile;

@Component
@Profile("development")
public class DevDatabaseConfig {
    // Используется в профиле development
}

@Component
@Profile("production")
public class ProdDatabaseConfig {
    // Используется в профиле production
}

Полный пример слоистого приложения

// 1. Data Layer
@Repository
public class UserRepository {
    // Доступ к БД
}

// 2. Service Layer
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User createUser(String name) {
        // Бизнес-логика
        return userRepository.save(new User(name));
    }
}

// 3. Controller Layer
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user.getName());
    }
}

// 4. Configuration
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

Ключевые моменты

  • @Component отмечает класс как управляемый бин Spring
  • @Service, @Repository, @Controller — специализированные версии
  • Spring автоматически управляет жизненным циклом
  • Зависимости внедряются через конструктор, setter или field injection
  • По умолчанию область видимости — singleton
  • Можно задавать custom имена и скоп
  • @PostConstruct и @PreDestroy для инициализации и очистки
  • Component scanning должен быть настроен

@Component — это основной механизм для управления компонентами в Spring приложениях.

Что такое @Component? | PrepBro