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

Является ли Controller бином в Spring?

2.0 Middle🔥 181 комментариев
#Spring Boot и Spring Data#Spring Framework

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

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

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

Является ли Controller бином в Spring

Да, Controller является бином в Spring. Когда ты аннотируешь класс с @Controller, @RestController или другими специализированными аннотациями, Spring автоматически создает и регистрирует этот класс как управляемый бин в контексте приложения.

Что такое бин в Spring

Бин (Bean) — это объект, которым управляет Spring IoC контейнер. Контейнер отвечает за:

  • Создание экземпляра
  • Инициализацию
  • Внедрение зависимостей
  • Управление жизненным циклом
  • Удаление из памяти

Как Controller становится бином

Когда Spring запускает приложение, он сканирует classpath в поисках классов с определенными аннотациями:

@RestController  // Это аннотация, которая делает класс бином
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired  // Внедрение зависимостей
    private UserService userService;
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

Spring выполняет следующие шаги:

  1. Обнаруживает @RestController на классе UserController
  2. Создает экземпляр: new UserController()
  3. Ищет все поля с @Autowired
  4. Внедряет зависимость UserService в поле
  5. Регистрирует это в контексте как бин
  6. Делает его доступным для инъекции в другие классы

Иерархия аннотаций

@RestController наследует функционал от @Controller:

// @RestController это:
@Controller
@ResponseBody
public class UserController { }

// Эквивалентно:
@Component  // Основная аннотация для создания бина
public class UserController { }

Все эти аннотации (@Controller, @Service, @Repository, @Component) — это стереотипы, которые указывают Spring создать бин.

Пример: Регистрация в контексте

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        // Spring создает контекст и регистрирует все бины
        ApplicationContext context = SpringApplication.run(Application.class, args);
        
        // Ты можешь получить бин из контекста
        UserController controller = context.getBean(UserController.class);
        System.out.println("Это бин: " + controller);
        
        // Или получить по имени
        UserController controller2 = (UserController) context.getBean("userController");
    }
}

Выво́д:

Это бин: com.example.controller.UserController@12345678

Жизненный цикл бина (Controller)

Spring управляет полным жизненным циклом:

@RestController
public class UserController implements InitializingBean, DisposableBean {
    
    public UserController() {
        System.out.println("1. Конструктор вызван");
    }
    
    @Autowired
    public void setUserService(UserService userService) {
        System.out.println("2. Зависимость внедрена");
    }
    
    @PostConstruct
    public void init() {
        System.out.println("3. Инициализация после создания");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("4. InitializingBean.afterPropertiesSet()");
    }
    
    @PreDestroy
    public void destroy() {
        System.out.println("5. Очистка ресурсов перед удалением");
    }
}

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

По умолчанию бины имеют область видимости Singleton — создается один экземпляр на все приложение:

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

Возможны другие области:

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

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

Как проверить, что это бин

@RestController
@RequestMapping("/api")
public class TestController {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @GetMapping("/check-bean")
    public String checkBean() {
        boolean isBean = applicationContext.containsBean("testController");
        if (isBean) {
            Object bean = applicationContext.getBean("testController");
            return "Controller является бином: " + bean.getClass().getName();
        }
        return "Controller не является бином";
    }
}

Инъекция в другие бины

Поскольку Controller — это бин, его можно внедрить в другие компоненты:

@Service
public class MyService {
    
    @Autowired
    private UserController userController;  // Внедрение контроллера
    
    public void doSomething() {
        // Используем контроллер (редко, но возможно)
        userController.getUser(1L);
    }
}

Однако это плохая практика — обычно зависимости идут в обратном направлении (Controller зависит от Service, не наоборот).

Заключение

Controller в Spring всегда является бином, независимо от того, используешь ли ты @Controller или @RestController. Spring автоматически:

  • Создает экземпляр класса
  • Регистрирует его в контексте приложения
  • Управляет его жизненным циклом
  • Внедряет зависимости
  • Делает доступным для инъекции в другие компоненты

Это является ключевой особенностью Spring Framework и позволяет управлять приложением декларативно, используя аннотации.