← Назад к вопросам
Какими обладаешь знаниями в Spring
1.3 Junior🔥 161 комментариев
#Soft Skills и карьера#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Знания в Spring Framework: Полный обзор
Spring Ecosystem
Spring — не один фреймворк, а целая экосистема проектов:
Spring Ecosystem
├─ Spring Framework (Core)
│ ├─ Core Container (IoC, DI)
│ ├─ Aspect-Oriented Programming (AOP)
│ ├─ Data Access / Transaction Management
│ └─ Web Framework (Spring MVC, WebFlux)
├─ Spring Boot (Production-ready)
├─ Spring Cloud (Microservices)
├─ Spring Data (Data access)
├─ Spring Security (Authentication & Authorization)
├─ Spring Integration (Message-driven apps)
└─ Spring Batch (Batch processing)
1. Spring Core (IoC Container)
Inversion of Control (IoC)
// Без Spring: управляем зависимостями сами
public class UserService {
private UserRepository userRepository;
private EmailService emailService;
public UserService() {
// Мы создаём зависимости вручную
this.userRepository = new UserRepository();
this.emailService = new EmailService();
}
}
// Проблемы: сложно тестировать, меняется в одном месте -> нужно обновлять везде
// С Spring: Spring управляет зависимостями
@Service
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
// Spring IoC контейнер создаёт и внедряет бины
public UserService(UserRepository userRepository,
EmailService emailService) {
this.userRepository = userRepository;
this.emailService = emailService;
}
}
// Spring бины (beans):
@Service
public class UserService { }
@Repository
public class UserRepository { }
@Component
public class EmailService { }
// Spring автоматически создаёт экземпляры и связывает их
Dependency Injection
// Three ways to inject dependencies:
// 1. Constructor Injection (рекомендуется)
@Service
public class OrderService {
private final UserRepository userRepository;
private final PaymentGateway paymentGateway;
public OrderService(UserRepository userRepository,
PaymentGateway paymentGateway) {
this.userRepository = userRepository;
this.paymentGateway = paymentGateway;
}
}
// 2. Setter Injection (устаревает)
@Service
public class OrderService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// 3. Field Injection (анти-паттерн)
@Service
public class OrderService {
@Autowired
private UserRepository userRepository; // Сложнее тестировать
}
Bean Lifecycle
// Bean проходит через несколько этапов:
@Component
public class MyBean implements InitializingBean, DisposableBean {
// 1. Constructor
public MyBean() {
System.out.println("1. Constructor called");
}
// 2. Setter injection (если есть)
// 3. InitializingBean
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("3. InitializingBean.afterPropertiesSet()");
}
// 4. @PostConstruct
@PostConstruct
public void init() {
System.out.println("4. @PostConstruct");
}
// 5. Bean is ready to use
public void doSomething() {
System.out.println("5. Bean in use");
}
// 6. @PreDestroy
@PreDestroy
public void cleanup() {
System.out.println("6. @PreDestroy");
}
// 7. DisposableBean
@Override
public void destroy() throws Exception {
System.out.println("7. DisposableBean.destroy()");
}
}
Bean Scopes
// 1. Singleton (default)
@Scope("singleton")
@Component
public class SingletonService { }
// Один экземпляр на весь ApplicationContext
// 2. Prototype
@Scope("prototype")
@Component
public class PrototypeService { }
// Новый экземпляр каждый раз
// 3. Request (Web)
@Scope("request")
@Component
public class RequestService { }
// Новый экземпляр на каждый HTTP запрос
// 4. Session (Web)
@Scope("session")
@Component
public class SessionService { }
// Новый экземпляр на каждую HTTP сессию
// 5. Application (Web)
@Scope("application")
@Component
public class ApplicationService { }
// Один экземпляр на весь ServletContext
2. Spring Web MVC
Controllers
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// GET /api/users
@GetMapping
public List<User> getAll() {
return userService.findAll();
}
// GET /api/users/{id}
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
return userService.findById(id);
}
// POST /api/users
@PostMapping
public ResponseEntity<User> create(@RequestBody CreateUserRequest request) {
User user = userService.create(request.getName(), request.getEmail());
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
// PUT /api/users/{id}
@PutMapping("/{id}")
public User update(@PathVariable Long id, @RequestBody UpdateUserRequest request) {
return userService.update(id, request.getName());
}
// DELETE /api/users/{id}
@DeleteMapping("/{id}")
public ResponseEntity<?> delete(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
Request/Response Handling
// Request body
@PostMapping
public User create(@RequestBody User user) { }
// Path variable
@GetMapping("/{id}")
public User getById(@PathVariable Long id) { }
// Query parameter
@GetMapping
public List<User> search(@RequestParam String name) { }
// GET /api/users?name=John
// Request header
@GetMapping
public User get(@RequestHeader("X-User-Id") String userId) { }
// Response status
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@RequestBody User user) { }
// ResponseEntity (full control)
@GetMapping("/{id}")
public ResponseEntity<User> get(@PathVariable Long id) {
return ResponseEntity
.ok()
.header("X-Custom-Header", "value")
.body(user);
}
3. Spring Data JPA
Repository Pattern
// Интерфейс
public interface UserRepository extends JpaRepository<User, Long> {
// Spring генерирует реализацию автоматически
User findByEmail(String email);
List<User> findByAgeGreaterThan(int age);
@Query("SELECT u FROM User u WHERE u.email LIKE %:email%")
List<User> searchByEmail(@Param("email") String email);
@Modifying
@Query("UPDATE User u SET u.active = true WHERE u.id = :id")
void activate(@Param("id") Long id);
}
// Использование
@RestController
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getByEmail(String email) {
return userRepository.findByEmail(email);
}
}
JPA Relationships
// One-to-Many
@Entity
public class User {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<Order> orders;
}
@Entity
public class Order {
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
// Many-to-Many
@Entity
public class User {
@ManyToMany
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
}
4. Spring Transaction Management
@Transactional
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final InventoryService inventoryService;
// Весь метод выполняется в одной транзакции
@Transactional
public void createOrder(Order order) {
// 1. Сохраняем заказ
orderRepository.save(order);
// 2. Уменьшаем инвентарь
inventoryService.reserve(order.getItems());
// Если ошибка -> всё откатывается (rollback)
// Если успех -> всё коммитится
}
// Read-only транзакция (оптимизация для чтения)
@Transactional(readOnly = true)
public Order getOrder(Long id) {
return orderRepository.findById(id).orElse(null);
}
// Не требует транзакции
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void logAction(String action) {
// ...
}
}
5. Spring AOP (Aspect-Oriented Programming)
Aspects
// Logging Aspect
@Aspect
@Component
public class LoggingAspect {
// Применяется ко всем методам в Service классах
@Around("execution(* com.example.service.*Service.*(..))")
public Object logMethodExecution(ProceedingJoinPoint joinPoint)
throws Throwable {
String methodName = joinPoint.getSignature().getName();
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed(); // Вызов оригинального метода
long duration = System.currentTimeMillis() - start;
System.out.println(methodName + " executed in " + duration + "ms");
return result;
} catch (Exception e) {
System.err.println(methodName + " failed: " + e.getMessage());
throw e;
}
}
}
// Используется автоматически
@Service
public class UserService {
public User getUser(Long id) {
// Будет залогирован автоматически
}
}
6. Spring Security
Authentication & Authorization
// Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.and()
.logout()
.logoutSuccessUrl("/login");
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
// Usage
@RestController
public class UserController {
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
// Spring Security обрабатывает аутентификацию
}
@GetMapping("/admin")
public String adminOnly() {
// Доступно только ADMIN
return "Admin content";
}
@GetMapping("/profile")
public User getProfile(@AuthenticationPrincipal UserDetails userDetails) {
// Получить текущего пользователя
return userRepository.findByUsername(userDetails.getUsername());
}
}
7. Spring Boot
Auto-configuration
// Вместо сотен конфигов нужен просто:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// application.properties
spring.datasource.url=jdbc:mysql://localhost/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
// Spring Boot автоматически создаёт:
// - DataSource
// - EntityManagerFactory
// - TransactionManager
// - Embedded Tomcat
// - Jackson для JSON
// - Logging
// - И ещё 100 компонентов
Properties & YAML
# application.yml
spring:
application:
name: my-app
datasource:
url: jdbc:mysql://localhost/mydb
username: root
password: password
jpa:
hibernate:
ddl-auto: update
show-sql: true
jackson:
serialization:
write-dates-as-timestamps: false
logging:
level:
root: INFO
com.example: DEBUG
pattern:
console: "%d %5p %40c{1.} : %m%n"
8. Spring Cloud
Microservices
// Service Discovery (Eureka)
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication { }
// Inter-service communication (Feign)
@FeignClient(name = "order-service")
public interface OrderServiceClient {
@GetMapping("/api/orders/{userId}")
List<Order> getUserOrders(@PathVariable Long userId);
}
// Circuit Breaker (Hystrix/Resilience4j)
@Service
public class OrderService {
private final OrderServiceClient orderServiceClient;
@CircuitBreaker(name = "orderService")
public List<Order> getUserOrders(Long userId) {
return orderServiceClient.getUserOrders(userId);
}
}
9. Spring Test
Testing
// Unit Test
@Test
public void testUserCreation() {
UserService service = new UserService(mockRepository);
User user = service.create("john@example.com", "John");
assertEquals("John", user.getName());
}
// Integration Test
@SpringBootTest
public class UserServiceIntegrationTest {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Test
@Transactional
public void testCompleteFlow() {
User user = userService.create("alice@example.com", "Alice");
User fromDB = userRepository.findByEmail("alice@example.com");
assertEquals(user.getName(), fromDB.getName());
}
}
// Mocking
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
public void testGetUser() throws Exception {
User user = new User(1L, "John", "john@example.com");
Mockito.when(userService.getUser(1L)).thenReturn(user);
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John"));
}
}
10. Advanced Topics
Profiles
// Different configs for different environments
@Configuration
@Profile("development")
public class DevConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
}
@Configuration
@Profile("production")
public class ProdConfig {
@Bean
public DataSource dataSource() {
return createProductionDataSource();
}
}
// application-dev.properties
# development specific config
// application-prod.properties
# production specific config
Conditional Beans
@Configuration
public class ConditionalConfig {
@Bean
@ConditionalOnProperty(name = "feature.cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new CaffeineCacheManager();
}
@Bean
@ConditionalOnClass(RedisTemplate.class)
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
}
Ключевые концепции
✅ IoC Container — управление объектами
✅ DI — внедрение зависимостей
✅ AOP — сквозная функциональность
✅ MVC — разделение ответственности
✅ Data Access — работа с БД
✅ Transaction Management — ACID гарантии
✅ Security — аутентификация и авторизация
✅ Testing — качество кода
✅ Boot — быстрый старт
✅ Cloud — микросервисы
Вывод
Spring ecosystem решает основные задачи:
- Dependency Injection — управление зависимостями
- Web Development — REST API, MVC
- Data Access — ORM через JPA
- Security — аутентификация и авторизация
- Testing — unit и integration тесты
- Microservices — облачные приложения
Best Practices:
- Constructor injection (не field injection)
- Service-Repository pattern
- Использовать Spring Boot для нового проекта
- Писать тесты (Unit + Integration)
- Использовать Spring Security для защиты
- DRY и Single Responsibility Principle
Spring — индустриальный стандарт для Java веб-разработки.