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

Какие паттерны используются в Spring Framework

2.0 Middle🔥 141 комментариев
#SOLID и паттерны проектирования#Spring Framework

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

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

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

Паттерны в Spring Framework

Spring Framework основан на нескольких фундаментальных паттернах проектирования, которые обеспечивают его мощь и гибкость. Понимание этих паттернов критично для эффективной работы с Spring.

1. Inversion of Control (IoC) паттерн

Это главный паттерн Spring. Вместо того, чтобы ваш код создавал объекты и управлял их жизненным циклом, это делает Spring контейнер.

// Без IoC (плохо)
public class OrderService {
    private UserRepository userRepository = new UserRepository();
    private EmailService emailService = new EmailService();
    
    public void createOrder(String userId) {
        // Жёстко завязано на конкретные реализации
    }
}

// С IoC (хорошо)
@Service
public class OrderService {
    private final UserRepository userRepository;
    private final EmailService emailService;
    
    public OrderService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }
}

2. Dependency Injection (DI) паттерн

Часть IoC паттерна. Spring инъецирует зависимости через конструктор, setter или field injection.

// Constructor injection (рекомендуется)
@Service
public class UserService {
    private final UserRepository repository;
    
    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

// Setter injection
@Service
public class UserService {
    private UserRepository repository;
    
    @Autowired
    public void setRepository(UserRepository repository) {
        this.repository = repository;
    }
}

// Field injection (не рекомендуется)
@Service
public class UserService {
    @Autowired
    private UserRepository repository;
}

3. Singleton паттерн

По умолчанию Spring создаёт бины как синглтоны — один экземпляр на всё приложение.

@Service
@Scope("singleton")  // По умолчанию
public class UserService {
    // Один экземпляр на всё приложение
}

// ApplicationContext.getBean() всегда возвращает одно и то же
UserService service1 = context.getBean(UserService.class);
UserService service2 = context.getBean(UserService.class);
assert service1 == service2;  // true

4. Factory паттерн

Spring использует Factory паттерн для создания бинов. @Bean методы — это явное применение этого паттерна.

@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(hikariConfig());
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

Фабрика может быть и более сложной:

@Configuration
public class DatabaseFactory {
    @Bean
    public UserRepository userRepository(DataSource dataSource) {
        if (isProduction()) {
            return new PostgresUserRepository(dataSource);
        } else {
            return new MockUserRepository();
        }
    }
}

5. Proxy паттерн

Spring использует прокси для AOP (Aspect-Oriented Programming). Когда вы применяете @Transactional или @Cacheable, Spring обёртывает ваш бин прокси.

@Service
public class UserService {
    @Transactional  // Spring создаёт прокси с логикой транзакций
    public User createUser(String name) {
        // Логика создания пользователя
    }
    
    @Cacheable("users")
    public User getUser(Long id) {
        // Spring кеширует результат
    }
}

// Spring создаёт что-то вроде:
public class UserServiceProxy extends UserService {
    @Override
    public User createUser(String name) {
        // Начало транзакции
        try {
            return super.createUser(name);
        } finally {
            // Коммит или откат
        }
    }
}

6. Observer паттерн

Spring Event система основана на Observer паттерне.

// Событие
public class UserCreatedEvent extends ApplicationEvent {
    private final String username;
    
    public UserCreatedEvent(Object source, String username) {
        super(source);
        this.username = username;
    }
    
    public String getUsername() {
        return username;
    }
}

// Publisher
@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher publisher;
    
    public void createUser(String name) {
        // Логика создания
        publisher.publishEvent(new UserCreatedEvent(this, name));
    }
}

// Observer
@Component
public class EmailNotifier {
    @EventListener
    public void onUserCreated(UserCreatedEvent event) {
        sendEmail(event.getUsername());
    }
}

7. Strategy паттерн

Используется для выбора различных реализаций в зависимости от конфигурации.

public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

@Component
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(BigDecimal amount) {
        // Оплата кредитной картой
    }
}

@Component
public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(BigDecimal amount) {
        // Оплата через PayPal
    }
}

@Service
public class PaymentProcessor {
    private final Map<String, PaymentStrategy> strategies;
    
    public PaymentProcessor(List<PaymentStrategy> strategies) {
        this.strategies = strategies.stream()
            .collect(Collectors.toMap(s -> s.getClass().getSimpleName(), s -> s));
    }
    
    public void process(String method, BigDecimal amount) {
        strategies.get(method).pay(amount);
    }
}

8. Template Method паттерн

Используется в классах типа JdbcTemplate, RestTemplate.

@Component
public class JdbcUserRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public User findById(Long id) {
        return jdbcTemplate.queryForObject(
            "SELECT * FROM users WHERE id = ?",
            new Object[]{id},
            (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"))
        );
    }
}

9. Decorator паттерн

АOP используется для декорирования методов функциональностью типа логирования, мониторинга.

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))") 
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Calling method: " + joinPoint.getSignature());
    }
}

10. Chain of Responsibility паттерн

Используется в Spring Security для цепи фильтров.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .httpBasic()
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/");
    }
}

Итоги

Spring Framework использует множество паттернов для обеспечения:

  • Гибкости — через Dependency Injection
  • Расширяемости — через Strategy и Factory паттерны
  • Модульности — через разделение ответственности
  • Кросскатинга concerns — через AOP
  • Асинхронности — через Observer паттерн

Понимание этих паттернов поможет вам писать более качественный и поддерживаемый код в Spring приложениях.