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

Что такое аннотация Autowired?

1.2 Junior🔥 221 комментариев
#Spring Framework

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

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

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

# Аннотация @Autowired

@Autowired — это аннотация Spring Framework, которая автоматически внедряет (инъектирует) зависимости в bean. Это часть Dependency Injection (DI) контейнера Spring и упрощает управление зависимостями между объектами.

Как работает @Autowired?

Cпring контейнер ищет bean подходящего типа и автоматически присваивает его полю или параметру конструктора/метода.

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

1. Внедрение через поле (Field Injection)

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // Spring присвоит сюда bean
    
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

2. Внедрение через сеттер (Setter Injection)

@Service
public class UserService {
    private UserRepository userRepository;
    
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

3. Внедрение через конструктор (Constructor Injection) — РЕКОМЕНДУЕТСЯ

@Service
public class UserService {
    private final UserRepository userRepository;
    
    // Spring автоматически вызовет конструктор и внедрит зависимости
    @Autowired // можно опустить в Spring 4.3+, если конструктор один
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

Пример реальной работы

// 1. Определяем интерфейс
public interface UserRepository {
    User findById(Long id);
}

// 2. Реализуем
@Repository
public class UserRepositoryImpl implements UserRepository {
    @Override
    public User findById(Long id) {
        // логика доступа к БД
        return new User(id, "John");
    }
}

// 3. Используем @Autowired
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // Spring найдёт UserRepositoryImpl
    
    public User getUser(Long id) {
        return userRepository.findById(id);
    }
}

// 4. Используем сервис
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUser(id);
    }
}

Параметр required

// По умолчанию required = true (выбросит exception, если bean не найден)
@Autowired
private UserRepository userRepository;

// Если bean может отсутствовать, используй required = false
@Autowired(required = false)
private Logger logger;

Конфликт: несколько реализаций одного интерфейса

public interface UserRepository {}

@Repository("mysql")
public class MySqlUserRepository implements UserRepository {}

@Repository("postgres")
public class PostgresUserRepository implements UserRepository {}

// ОШИБКА: Spring не знает какую реализацию внедрить!
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // Какую выбрать?
}

// РЕШЕНИЕ 1: @Qualifier
@Service
public class UserService {
    @Autowired
    @Qualifier("postgres") // явно указываем
    private UserRepository userRepository;
}

// РЕШЕНИЕ 2: @Primary
@Repository
@Primary // эта реализация используется по умолчанию
public class PostgresUserRepository implements UserRepository {}

Современная альтернатива: конструктор без @Autowired

// В Spring 4.3+ можно опустить @Autowired
@Service
public class UserService {
    private final UserRepository userRepository;
    
    // Spring автоматически внедрит, если конструктор один
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

// Или с Lombok:
@Service
@RequiredArgsConstructor // автогенерирует конструктор
public class UserService {
    private final UserRepository userRepository;
}

Почему Constructor Injection лучше?

  1. Immutability — зависимости final, не могут измениться
  2. Testability — легко передать mock в тестах
  3. Явность — видно все зависимости в конструкторе
  4. Избегает NullPointerException — если зависимость null, конструктор не вызовется

Жизненный цикл @Autowired

  1. Spring создаёт bean (вызывает конструктор)
  2. Проверяет все поля/методы с @Autowired
  3. Ищет matching bean в контексте
  4. Внедряет найденный bean
  5. Вызывает @PostConstruct методы
  6. Bean готов к использованию
Что такое аннотация Autowired? | PrepBro