본문 바로가기
백엔드 자료집/Spring

[Spring] Spring 핵심 개념

by cogito30 2025. 3. 4.

Spring 핵심 기능

- IoC/DI, AOP, PSA

- Spring Framework

 - Spring Boot, Spring Data, Spring Batch, Spring Cloud, Spring Security에 중점

- 필요하나 모듈만 선택하여 사용 가능

- 마이크로서비스 아키텍처로 변환 중

- "테스트의 용이성"과 "느슨한 결함"에 중점을 두고 개발

 

IoC, DI

- IoC(제어의 역전): Spring Container가 객체를 관리

- DI(의존성 주입): 객체 사용을 위해 외부에서 주입을 받음. 순환 참조 방지. 코드테스트 유리

 

 

AOP

- AOP(Aspect Oriented Programming): 관점지향 프로그램

- Spring Application의 MVC Web Application에서는 Web Layer + Business Layer, Data Layer로 정의

- Web Layer: REST API 제공. 클라이언트 중심 로직 적용

- Business Layer: 내부 정책에 따른 로직 개발

- Data Layer: 데이터 베이스 및 외부와 연동 처리

 

(주요 Annotation)

더보기
Annotation Descriptoion
@Aspect AOP를 정의하는 Class에 할당
@Pointcut 기능을 어디에 적용시킬지 AOP 적용 지점 설정
@Before 메소드 실행하기 이전 실행
@After 메소드가 성공/예외 발생 모든 경우에 실행
@AfterReturning 메소드 호출 성골시 실행
@AfterThrowing 메소드 호출 실패/예외 발생시 실행
@Around  Before/After 모두 제어

 

 (AOP 실습)

1) Spring Initializr 생성 후 프로젝트 실행

2) build.gradle의 dependencies에 implementation 'org.springframework.boot:spring-boot-starter-aop' 추가

3) API 설계 후 구현

더보기

(Class: RestApiController.java)

@RestController
@RequestMapping("/api")
public class RestApiController {
    @GetMapping("/get/{id}")
    public String get(@PathVariable Long id, @RequestParam String name) {
        return id + " " + name;
    }
    
    @PostMapping("/post")
    public User post(@RequestBody User user) {
    
        return user;
    }
    
    @Decode
    @PostMapping("/put")
    public User put(@RequestBody User user) {
        return user;
    }
    
    @Timer
    @DeleteMapping("/delete")
    public void delete() throws InterruptedExecution {
        Thread.sleep(1000 * 2);
    
    }
}

(Class: User)

public class User {
    private String id;
    private Interger password;
    
    // getter
    
    //setter
    
    public String toString() {
        return "User{" +
            "id= '" + id + '\'' +
            ", pw='" + pw + '\'' +
            '}';
    }
}

(Class: ParameterAop)

@Aspect
@Component
public class ParameterAop {
    
    @Pointcut("execution(* com.example.aop.controller..*.*(..))")
    private void cut() {
    
    }
    
    @Before("cut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println(method.getName());
        
        Object[] args = joinPoint.getArgs();
        
        for(Object obj: args) {
            System.out.println("type: " + obj.getClass().getSimpleName());
            
        }
    
    }
    
    @AfterReturning("value = cut()", returning = "returnObj")
    public void afterReturn(JoinPoint joinPoint, Object returnObj) {

    }
}

(Class: TimerAop)

@Aspect
@Component
public class TimerAop {

    @Pointcut("execution(* com.example.aop.controller..*.*(..))")
    private void cut() {
    
    }
    
    @Pointcut("@annotation(com.example.aop.annotation.Timer)")
    private void enableTimer() {
    }
    
    @Around("cut() && enableTimer()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        Stopwatch.stopWatch = new StopWatch();
        stopWatch.start();
    
        Object result = joinPoint.proceed();  // 메서드 실행후 객체 리턴
        
        stopWatch.stop();
        
        System.out.println("total time : " + stopWatch.getTotalTimeSeconds());
    }
    
}

(Annotation: Timer)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {

}

(Class: DecodeAop)

@Aspect
@Component
public class DecodeAop {
    @Pointcut()
    private void cut() {
    
    }
    
    @Pointcut("@annotation(com.example.aop.annotation.Decode)")
    private void enableDecode(){
    }
    
    @Before("cut() && enableDecode()")
    public void before(JoinPoint joinPoint) throws UnsupportedEncodingException {
        Object[] args = joinPoint.getArgs();
        
        for (Object arg : args) {
        if (arg instanceof User) {
                User user = User.class.cast(arg);
                String base64Email = user.getEmail();
                String email =new String(Base64.getDecoder().decode(base64Email), "UTF-8");
                user.setEmail(email);
            }
        }
    }
    
    @AfterReturning(value = "cut() && enableDecode()", returning = "returnObj")
    public void afterReturn(JoinPoint joinPoint, Object returnObj) {
        if (returnObj instanceof User) {
            User user = User.class.cast(returnObj);
            String email = user.getEmail();
            String base64Email = Base64.getEncoder().encodeToString(email.getBytes());
            user.setEmail(base64Email);
        }    
    }

}

(Interface: Decode)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Decode {

}

ObjectMapper

- Text/Json   Object

- Object → Text/Jsson

더보기
var objectMapper = new ObjectMapper();

var user = new User(...);
var text = objectMapper.writeValueAsString(user);
var objectUser = objectMapper.readValue(text, User.class);

(JSON 파싱)

String json = objectMapper.writeValueAsString(user);
JsonNode jsonNode = jsonNode.get("name").asText();
String _name = jsonNode.get("name").asText();
int _age = jsonNode.get("age").asInt();


JsonNode cars = jsonNode.get("cars");
ArrayNode arrayNode = (ArrayNode)cars;

// Object를 특정 Type으로 변경
List<Car> _cars = objectMapper.convertValue(arrayNode, new TypeReference<List<Car>>(){});

ObjectNode objectNode = (ObjectNode) jsonNode;
objectNode.put("names", "lee");
objectNode.put("age", 30);
System.println(objectNode.toPrettyString());

- Object Mapper로 JSON 접근

- ObjectMapper는 Java Library

 

자주 사용하는 Spring Annotation

(Spring)

Annotation Descriptioin
@SpringBootApplication Spring Boot Application으로 설정
@Controller View를 제공하는 Controller로 설정
@Valid POJO Java Class 검증
@Configuration 1개 이상의 Bean을 등록
@Component 1개의 Class를 Bean 등록시 사용
@Bean 1개의 외부 library로부터 생성한 객체 등록시 사용. 메서드에 사용
@Autowired DI를 위한 곳에 사용
@Qualifier 2개 이상의 Bean이 있을 때 어떤 Bean을 사용할지 명시적으로 지정
@Resource @Autowired + @Qualifier의 개념
@Aspect AOP 적용시 사용
@Before AOP 메서드 이전 호출 지정
@After AOP 메서드 호출 이후 지정 (예외 발생 포함)
@Around AOP 이전/이후 모두 포함(예외 발생 포함)
@AfterReturning AOP 이후 정상일 때 실행
@AfterThrowing AOP 이후 에러 발생시 실행

 

(Rest API)

Annotation Descriptoin
@RestController REST API를 제공하는 controller로 설정
@RequestMapping URL 주소를 매핑
@GetMapping HTTP Get 메서드 URL 주소 매핑
@PostMapping HTTP Post 메서드 URL 주소 매핑
@PutMapping HTTP Put 메서드 URL 주소 매핑
@DeleteMapping HTTP Delete 메서드 URL 주소 매핑
@RequestParam URL Query Parameter 매핑
@RequestBody HTTP Body를 Parsing해서 매핑

 

 

'백엔드 자료집 > Spring' 카테고리의 다른 글

[Spring] Spring 기능  (1) 2025.03.05
[Spring] 참고자료  (0) 2025.03.03