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

Какие знаешь аннотации для определения бинов?

1.3 Junior🔥 231 комментариев
#Spring Framework

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

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

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

# Аннотации для определения бинов в Spring

В Spring Framework существует множество аннотаций для определения управляемых компонентов (бинов). Рассмотрим основные из них.

1. @Component

Основная аннотация для создания Spring бина. Используется как универсальный маркер для любого управляемого компонента:

@Component
public class MyComponent {
    public void doSomething() {
        System.out.println("Doing something");
    }
}

Spring автоматически обнаружит этот класс при сканировании classpath и создаст бин.

2. @Service

Специализированная аннотация для бизнес-логики. Семантически указывает, что класс содержит бизнес-сервис:

@Service
public class UserService {
    public User createUser(String name) {
        // бизнес-логика
        return new User(name);
    }
}

Когда использовать: для классов, содержащих основную бизнес-логику приложения.

3. @Repository

Аннотация для классов, работающих с БД (Data Access Object pattern). Обеспечивает трансляцию исключений БД в Spring DataAccessException:

@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 UserRowMapper(), id);
    }
    
    public void save(User user) {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getName(), user.getEmail());
    }
}

Преимущества:

  • PersistenceExceptionTranslator автоматически преобразует проверяемые исключения в unchecked исключения
  • Улучшает читаемость кода

4. @Controller

Аннотация для контроллеров в Spring MVC. Обрабатывает HTTP запросы:

@Controller
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/users/{id}")
    public String getUser(@PathVariable Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "user-detail";
    }
}

5. @RestController

Комбинация @Controller + @ResponseBody. Используется для REST API, возвращает JSON/XML вместо представления:

@RestController
@RequestMapping("/api/users")
public class UserRestController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    @PostMapping
    public User createUser(@RequestBody UserDTO dto) {
        return userService.createUser(dto.getName());
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
    }
}

6. @Configuration

Аннотация для классов, содержащих конфигурацию приложения. Используется вместе с методами, отмеченными @Bean:

@Configuration
public class AppConfig {
    
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/mydb");
        dataSource.setUsername("user");
        dataSource.setPassword("password");
        return dataSource;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
    @Bean
    public UserRepository userRepository(JdbcTemplate jdbcTemplate) {
        return new UserRepository(jdbcTemplate);
    }
}

7. @Bean

Аннотация для методов, которые создают и возвращают управляемые объекты. Используется внутри @Configuration классов:

@Configuration
public class ServiceConfig {
    
    @Bean
    public UserService userService() {
        return new UserService();
    }
    
    @Bean
    public UserValidator userValidator() {
        return new UserValidator();
    }
    
    // Метод можно сделать зависимостью для другого бина
    @Bean
    public OrderService orderService(UserService userService) {
        return new OrderService(userService);
    }
}

8. @Conditional

Создать бин только при выполнении определенного условия:

@Component
@ConditionalOnProperty(name = "feature.advanced.enabled", havingValue = "true")
public class AdvancedFeature {
    // этот бин будет создан только если feature.advanced.enabled=true
}

@Bean
@ConditionalOnBean(DataSource.class)
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

9. @Scope

Определяет область видимости бина (сколько экземпляров создается):

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

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

// Request scope (только в веб-приложениях)
@Component
@Scope("request")
public class RequestService {}

// Session scope (только в веб-приложениях)
@Component
@Scope("session")
public class SessionService {}

10. @Lazy

Отложенная инициализация бина (создается только при первом использовании):

@Component
@Lazy
public class ExpensiveService {
    public ExpensiveService() {
        System.out.println("ExpensiveService инициализирована");
    }
}

@Service
public class MyService {
    @Autowired
    @Lazy
    private ExpensiveService expensiveService;
    // expensiveService будет создана только при первом обращении
}

11. @Primary

Указать, какой бин использовать по умолчанию при наличии нескольких реализаций:

interface DataSource {}

@Component
@Primary
public class PostgresDataSource implements DataSource {}

@Component
public class MySQLDataSource implements DataSource {}

@Service
public class DatabaseService {
    private final DataSource dataSource;
    
    // будет внедрен PostgresDataSource (помечен @Primary)
    public DatabaseService(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

12. @Qualifier

Указать конкретный бин по имени при наличии нескольких реализаций:

@Component("postgresSource")
public class PostgresDataSource implements DataSource {}

@Component("mysqlSource")
public class MySQLDataSource implements DataSource {}

@Service
public class DatabaseService {
    private final DataSource dataSource;
    
    // явно указываем, какой бин использовать
    public DatabaseService(@Qualifier("mysqlSource") DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

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

АннотацияНазначениеОбластьПримеры
@ComponentУниверсальный компонентЛюбойUtility, Helper классы
@ServiceБизнес-логикаСлой сервисовUserService, OrderService
@RepositoryДоступ к даннымСлой доступаUserRepository, OrderRepository
@ControllerОбработка HTTP (MVC)Веб-слойUserController
@RestControllerREST APIВеб-слойAPI контроллеры
@ConfigurationКонфигурацияКонфигурацияAppConfig, SecurityConfig
@BeanСоздание объектовКонфигурацияМетоды в @Configuration

Практический пример полной архитектуры

// 1. Сущность
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String email;
}

// 2. Repository слой
@Repository
public class UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

// 3. Service слой
@Service
public class UserService {
    private final UserRepository userRepository;
    private final MailService mailService;
    
    public UserService(UserRepository userRepository, MailService mailService) {
        this.userRepository = userRepository;
        this.mailService = mailService;
    }
    
    public User registerUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user);
        mailService.sendWelcomeEmail(email);
        return user;
    }
}

// 4. Controller слой
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;
    
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @PostMapping
    public User createUser(@RequestBody UserDTO dto) {
        return userService.registerUser(dto.getName(), dto.getEmail());
    }
}

// 5. Configuration
@Configuration
public class AppConfig {
    // дополнительная конфигурация при необходимости
}

Правильное использование этих аннотаций обеспечивает чистую архитектуру, слабую связанность и высокую тестируемость кода.

Какие знаешь аннотации для определения бинов? | PrepBro