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

Как положить класс в контекст Spring

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

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

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

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

# Как положить класс в контекст Spring

В Spring контекст (ApplicationContext) автоматически управляет объектами, которые называются бины (beans). Есть несколько способов зарегистрировать класс в контексте.

Способ 1: Аннотация @Component

Самый простой способ — добавить аннотацию на класс:

import org.springframework.stereotype.Component;

@Component
public class UserService {
    public void saveUser(String name) {
        System.out.println("Сохраняю пользователя: " + name);
    }
}

Spring автоматически создаст бин этого класса и разместит его в контексте. Имя бина по умолчанию — имя класса в lowercase: userService.

Способ 2: Специализированные аннотации

Для разных слоёв приложения есть специальные аннотации:

// Контроллер (слой представления)
@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // ...
    }
}

// Сервис (бизнес-логика)
@Service
public class UserService {
    public User findById(Long id) {
        // ...
    }
}

// Репозиторий (доступ к БД)
@Repository
public class UserRepository extends JpaRepository<User, Long> {
    // ...
}

// Конфигурация
@Configuration
public class AppConfig {
    // ...
}

Все эти аннотации наследуются от @Component и работают одинаково, но добавляют семантику.

Способ 3: Метод @Bean в @Configuration

Если хочешь больше контроля или регистрируешь класс из library:

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

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserService();
    }
    
    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
    
    // С параметрами
    @Bean
    public EmailService emailService(ConfigProperties props) {
        return new EmailService(props.getSmtpServer());
    }
    
    // С именем
    @Bean(name = "adminService")
    public UserService adminUserService() {
        return new UserService(true);  // true = режим администратора
    }
}

Способ 4: Автоматическое сканирование

По умолчанию Spring сканирует пакеты в поиске @Component аннотаций:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication  // Автоматически сканирует текущий пакет и подпакеты
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Если пакеты в других местах:

@Configuration
@ComponentScan(basePackages = {"com.example.service", "com.example.repository"})
public class ScanConfig {
}

Способ 5: Программная регистрация

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        
        // Получаем бин
        UserService userService = context.getBean(UserService.class);
        userService.saveUser("John");
    }
}

Или через Java конфиг:

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        
        UserService userService = context.getBean(UserService.class);
        userService.saveUser("John");
    }
}

Практический пример: многоуровневое приложение

// Модель
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
}

// Репозиторий
@Repository
public class UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

// Сервис
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User getUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }
    
    public void saveUser(User user) {
        userRepository.save(user);
    }
}

// Контроллер
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        userService.saveUser(user);
        return user;
    }
    
    @GetMapping("/{email}")
    public User getUser(@PathVariable String email) {
        return userService.getUserByEmail(email);
    }
}

// Точка входа
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // Spring автоматически:
        // 1. Сканирует @Component, @Service, @Repository, @Controller
        // 2. Создаёт экземпляры
        // 3. Внедряет зависимости через @Autowired
    }
}

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

@Component
public class MyBean implements InitializingBean, DisposableBean {
    
    // 1. Конструктор
    public MyBean() {
        System.out.println("1. Constructor");
    }
    
    // 2. Инициализация свойств через аннотацию
    @Autowired
    private SomeService service;
    
    // 3. После инициализации
    @PostConstruct
    public void init() {
        System.out.println("3. @PostConstruct");
        service.initialize();
    }
    
    // 4. Интерфейс InitializingBean
    @Override
    public void afterPropertiesSet() {
        System.out.println("4. InitializingBean.afterPropertiesSet()");
    }
    
    // 5. Перед уничтожением
    @PreDestroy
    public void cleanup() {
        System.out.println("5. @PreDestroy");
    }
    
    // 6. Интерфейс DisposableBean
    @Override
    public void destroy() {
        System.out.println("6. DisposableBean.destroy()");
    }
}

Получение бина из контекста

@Component
public class MyClass {
    @Autowired
    private UserService userService;  // Способ 1: Injection через аннотацию
    
    private final UserService userService2;  // Способ 2: Constructor Injection
    public MyClass(UserService userService2) {
        this.userService2 = userService2;
    }
    
    public void doSomething(ApplicationContext context) {
        // Способ 3: Получить вручную
        UserService service = context.getBean(UserService.class);
        // или по имени
        UserService service2 = (UserService) context.getBean("userService");
    }
}

Итог

Быстрый чеклист:

  1. Добавь @Component (или специализированную аннотацию) на класс
  2. Spring автоматически создаст бин и положит в контекст
  3. Используй @Autowired для внедрения зависимостей
  4. Для external библиотек используй @Configuration + @Bean
Как положить класс в контекст Spring | PrepBro