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

Какой используется паттерн при создании Bean?

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

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

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

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

Паттерны создания Bean в Spring Framework

Pри создании объектов (Bean) в Spring используется несколько паттернов проектирования, главный из которых — Factory Pattern, но также применяются другие.

1. Factory Pattern (основной)

Spring использует Factory Pattern для создания Bean'ов. Это позволяет абстрагировать логику создания объектов.

// Пример: Spring сам выступает как Factory
public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(Class<T> requiredType);
}

@Configuration
public class AppConfig {
    
    // Spring использует эту фабрику (метод) для создания Bean
    @Bean
    public UserService userService() {
        // Логика создания
        UserService service = new UserService();
        service.init();  // инициализация
        return service;
    }
}

// Использование
BeanFactory beanFactory = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = beanFactory.getBean(UserService.class);

2. Singleton Pattern

По умолчанию все Bean'ы в Spring — Singleton (одного экземпляра на приложение).

@Component
@Scope("singleton")  // По умолчанию
public class UserRepository {
    // Один экземпляр на приложение
    // Все инъекции получают одну и ту же ссылку
}

private static UserRepository instance;  // Внутри Spring

public static UserRepository getInstance() {
    if (instance == null) {
        instance = new UserRepository();
    }
    return instance;
}

Проблема и решение:

// ❌ ПРОБЛЕМА: Singleton с состоянием (not thread-safe)
@Component
public class UserSessionHolder {
    private User currentUser;  // Общее для всех потоков!
    
    public void setUser(User user) {
        this.currentUser = user;
    }
}

// ✅ РЕШЕНИЕ: Использовать Prototype или Request scope
@Component
@Scope("request")
public class UserSessionHolder {
    private User currentUser;  // Отдельно для каждого запроса
}

3. Dependency Injection Pattern

Spring реализует DI (Dependency Injection), а именно:

Constructor Injection (рекомендуется)

@Service
public class OrderService {
    private final UserRepository userRepository;
    private final PaymentService paymentService;
    
    // Инъекция через конструктор
    public OrderService(UserRepository userRepository,
                       PaymentService paymentService) {
        this.userRepository = userRepository;
        this.paymentService = paymentService;
    }
}
// Spring автоматически вызывает конструктор с нужными параметрами

Setter Injection

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

Field Injection (не рекомендуется)

@Service
public class OrderService {
    @Autowired
    private UserRepository userRepository;  // Spring инъектирует автоматически
}

4. Builder Pattern

Spring использует Builder для создания сложных объектов, например DataSource:

// Builder для DataSource
DataSource dataSource = DataSourceBuilder.create()
    .driverClassName("org.postgresql.Driver")
    .url("jdbc:postgresql://localhost:5432/mydb")
    .username("user")
    .password("pass")
    .build();

// Или в Bean методе
@Bean
public DataSource dataSource() {
    return DataSourceBuilder.create()
        .driverClassName("org.postgresql.Driver")
        .url("jdbc:postgresql://localhost/mydb")
        .build();
}

5. Template Method Pattern

Spring использует Template Method для жизненного цикла Bean'ов:

@Component
public class MyBean {
    
    // Template Method паттерн: Spring вызывает эти методы в определённом порядке
    
    @PostConstruct
    public void init() {
        System.out.println("1. Bean инициализирован");
    }
    
    public void doSomething() {
        System.out.println("2. Bean работает");
    }
    
    @PreDestroy
    public void destroy() {
        System.out.println("3. Bean уничтожается");
    }
}

// Жизненный цикл:
// 1. Создание объекта (Constructor)
// 2. @PostConstruct
// 3. Использование
// 4. @PreDestroy

6. Strategy Pattern

Выбор стратегии на основе условий:

// Различные реализации платёжных систем
public interface PaymentGateway {
    void process(double amount);
}

@Component("stripe")
public class StripePaymentGateway implements PaymentGateway {
    @Override
    public void process(double amount) { /* Stripe логика */ }
}

@Component("paypal")
public class PayPalPaymentGateway implements PaymentGateway {
    @Override
    public void process(double amount) { /* PayPal логика */ }
}

// Spring выбирает реализацию
@Service
public class OrderService {
    @Autowired
    @Qualifier("stripe")  // Выбираем стратегию
    private PaymentGateway paymentGateway;
}

7. Proxy Pattern

Spring использует прокси для создания bean'ов (особенно с @Transactional):

@Service
public class UserService {
    @Transactional  // Spring создаёт Proxy вокруг UserService
    public void saveUser(User user) {
        // Proxy добавляет логику управления транзакциями
        // Реальный сервис вызывается через proxy
    }
}

// Что происходит внутри:
// UserService service = new UserService();
// UserService proxy = new Proxy(service);  // обёртка с доп функционалом
// proxy.saveUser(user);  // вызовет логику транзакций, потом реальный сервис

8. Adapter Pattern

адаптирует компоненты с разными интерфейсами:

// Старый интерфейс
public interface OldUserService {
    User getUserById(int id);
}

// Новый интерфейс
public interface NewUserService {
    User getUser(Long id);
}

// Адаптер
@Component
public class UserServiceAdapter implements NewUserService {
    @Autowired
    private OldUserService oldService;
    
    @Override
    public User getUser(Long id) {
        return oldService.getUserById(id.intValue());
    }
}

9. Observer Pattern (Event-Driven)

Spring использует для событий:

// Событие
public class UserCreatedEvent extends ApplicationEvent {
    private User user;
    
    public UserCreatedEvent(Object source, User user) {
        super(source);
        this.user = user;
    }
}

// Издатель события
@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    public void createUser(User user) {
        userRepository.save(user);
        eventPublisher.publishEvent(new UserCreatedEvent(this, user));
    }
}

// Слушатель события
@Component
public class EmailNotificationListener {
    @EventListener
    public void onUserCreated(UserCreatedEvent event) {
        emailService.sendWelcome(event.getUser().getEmail());
    }
}

10. Abstract Factory Pattern

Создание семейств связанных объектов:

// Abstract Factory
public interface DataSourceFactory {
    DataSource createDataSource();
    ConnectionPool createConnectionPool();
}

@Configuration
@Profile("prod")
public class ProdDataSourceFactory implements DataSourceFactory {
    @Override
    public DataSource createDataSource() { /* Prod DataSource */ }
    
    @Override
    public ConnectionPool createConnectionPool() { /* Prod Pool */ }
}

@Configuration
@Profile("dev")
public class DevDataSourceFactory implements DataSourceFactory {
    @Override
    public DataSource createDataSource() { /* H2 DataSource */ }
    
    @Override
    public ConnectionPool createConnectionPool() { /* Dev Pool */ }
}

Жизненный цикл Bean'а (все паттерны в действии)

@Configuration
public class BeanLifecycleExample {
    
    @Bean
    public MyService myService() {
        // 1. Factory Pattern: фабрика создаёт объект
        return new MyService();
    }
}

@Component
public class MyService implements InitializingBean, DisposableBean {
    
    // 2. Constructor
    public MyService() {
        System.out.println("1. Конструктор");
    }
    
    // 3. Setter Injection
    @Autowired
    public void setDependency(Dependency dep) {
        System.out.println("2. Injection");
    }
    
    // 4. InitializingBean / @PostConstruct (Template Method)
    @PostConstruct
    public void init() {
        System.out.println("3. Инициализация");
    }
    
    // 5. DisposableBean / @PreDestroy
    @PreDestroy
    public void destroy() {
        System.out.println("4. Уничтожение");
    }
}

Выводы

ПаттернГде использует Spring
FactoryBean creation
SingletonDefault scope
Dependency Injection@Autowired, Constructor
BuilderDataSourceBuilder
Template MethodBean lifecycle
Strategy@Qualifier for implementations
Proxy@Transactional, AOP
AdapterIntegrations
ObserverApplicationEvent
Abstract FactoryProfiles, Conditional beans

Основной паттерн — Factory, но Spring применяет множество паттернов вместе для создания гибкой и мощной системы управления компонентами.