В Spring: если несколько классов инжектят один и тот же бин, будет ли создан один его экземпляр?

Ответ

Да, по умолчанию будет создан один экземпляр (singleton scope). Все зависимости получат ссылку на один и тот же объект бина.

Почему? Область видимости (scope) бина по умолчанию в Spring — singleton. Контейнер создает единственный экземпляр на все приложение и возвращает его при каждом запросе или инъекции.

Пример:

@Service // По умолчанию scope="singleton"
public class MyService {
    // Логика сервиса
}

@RestController
public class ControllerA {
    @Autowired
    private MyService service; // Получает ссылку на singleton-экземпляр MyService
}

@RestController
public class ControllerB {
    @Autowired
    private MyService service; // Получает ссылку на ТОТ ЖЕ singleton-экземпляр
}

Исключение: Если для бина явно задана другая область видимости (например, @Scope("prototype")), то для каждой инъекции будет создаваться новый экземпляр.

Ответ 18+ 🔞

А, слушай, вот это реально важный момент, про который народ частенько ебётся! Так, давай по полочкам, но с огоньком.

Вот представь себе: ты объявляешь какую-нибудь свою @Service или @Component. И думаешь: "О, я сейчас её впихну в два разных контроллера, и у меня там будет две независимые штуки, как в прототипе". А нихуя! Spring, этот хитрожопый фокусник, по умолчанию делает тебе один экземпляр на всю твою ебучую вселенную приложения. Это и есть singleton scope, дефолтная пизда.

Все, кто его просят — @Autowired, конструкторы, сеттеры — получают ссылку на один и тот же объект. Это как одна бутылка водки на всю компанию: все пьют из неё, и если кто-то её допил или, не дай бог, плюнул туда, то всем остальным тоже достанется. Вот так и с состоянием бина — если оно есть, и его меняют, то изменения видны всем.

Пример, чтобы совсем пиздец ясно стало:

@Service // Секретная приправа! scope="singleton" по умолчанию, ёпта!
public class MyService {
    private int counter = 0; // Вот эта хуйня — общая для всех!
    public int increment() { return ++counter; }
}

@RestController
public class ControllerA {
    @Autowired
    private MyService service; // Ссылка на ТУ САМУЮ бутылку

    @GetMapping("/incA")
    public int incA() {
        return service.increment(); // Увеличит общий счётчик
    }
}

@RestController
public class ControllerB {
    @Autowired
    private MyService service; // Ссылка на ТУ ЖЕ САМУЮ, блядь, бутылку!

    @GetMapping("/incB")
    public int incB() {
        return service.increment(); // Увеличит ТОТ ЖЕ САМЫЙ общий счётчик!
    }
}

Вызовешь /incA, потом /incB — счётчик пойдёт 1, 2, 3... Потому что это один объект, Карл! Все держат его за яйца.

А когда это НЕ работает? А вот когда ты явно говоришь: "Spring, ты чё, охуел? Мне на каждый раз новенький!" — ставишь аннотацию @Scope("prototype"). Тогда для каждой инъекции, для каждого запроса на бин, контейнер, этот ёбаный трудяга, будет создавать новый, свеженький экземпляр. Как одноразовые стаканчики — выпил, смял, выбросил, следующий чистый.

Так что запомни, дружище: по умолчанию — один на всех, как последняя пачка сигарет в окопе. Хочешь иначе — явно говори. А то потом удивляешься, откуда у всех в данных одни и те же глюки, а это просто singleton scope ебёт твой мозг. Всё, чих-пых!