Spring Framework

  • 엔터프라이즈 애플리케이션 개발에 주로 사용
  • 모듈화되어 있어 필요에 따라 특정 기능만 선택적으로 사용 가능
  • 객체 지향 언어의 특징을 살려낸 프레임워크 (캡슐화, 상속, 추상화, 다형성)

 

Spring Boot

  • 스프링 프레임워크를 기반으로, 간편하고 신속하게 애플리케이션을 개발할 수 있도록 돕는 도구
  • 자동 구성(Auto-configuration) 기능을 제공하여, 초기 설정 작업 자동화
  • 내장 WAS(Tomcat)을 제공하여, 애플리케이션을 별도의 서버 설정 없이 바로 실행 가능
  • `spring-boot-starter-web`를 빌드 관리 도구에 추가하면 웹 애플리케이션에 필요한 모든 종속성과 설정이 자동으로 구성

스프링 특징

1. POJO (Plain Old Java Object, =bean) 사용

  • 인터페이스를 구현하거나 특정 클래스를 상속할 필요가 없는 아주 간단한 자바 클래스
  • bean으로서 스프링 컨테이너에 의해 관리

2. DI (Dependency Injection, 의존성 주입)

  • `@Autowired` 은 스프링이 자동으로 해당 클래스에 다른 객체를 주입(연결)하기 위해 사용
  • 단위 테스트를 진행할 때 Mocked Service를 주입하도록 변경해서 테스트하기 용이
  • 생성자에 주입하는 경우에는 생성자가 하나라면 어노테이션 생략 가능하지만, 생성자가 2개 이상이라면 스프링이 어떤 생성자에 객체를 주입할지 지정할 수 있도록 어노테이션 필수
  • 생성자에 객체를 주입하지 않고, 필드 주입이나 세터 주입도 가능은 함(권장 X)
더보기

생성자 주입✅

final 키워드 사용 가능 -> 안전한 코드 작성 가능

@Component
public class PersonService {
    private final Person person;

    @Autowired  // 생성자가 하나면 생략 가능 (Spring 4.3 이상)
    public PersonService(Person person) {  
        this.person = person;
    }
}

 

필드 주입⚠️

final 키워드 사용 불가 -> 불변성 보장 X

주입된 객체에 접근시 NullPointerException 발생 가능

@Component
public class PersonService {
    @Autowired  // 직접 필드에 주입
    private Person person;
}

 

세터 주입

final 키워드 사용 불가 -> 불변성 보장 X

세터가 실행되지 않으면 주입된 객체는 null값을 가짐

@Component
public class PersonService {
    private Person person;

    @Autowired
    public void setPerson(Person person) {
        this.person = person;
    }
}

3. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

  • 핵심 로직과 부가 기능 분리
  • 여러 곳에서 반복되는 부가 기능을 하나의 애스펙트로 처리함으로써 중복 코드를 제거할 수 있음
  • `@Aspect`
    • 핵심 로직에 부가적인 기능 추가
    • ex. 로깅, 트랜잭션 관리, 보안 등을 분리해서 관리
  •  Join Point
    • Aspect가 적용될 수 있는 코드의 지점 (메서드 호출, 예외 발생, 객체 생성 지점 등)
  • Advice
    • 실제 실행할 코드
    • `@Before` : 조인 포인트에서 메서드 실행 전에 실행
    • `@After` : 조인 포인트에서 메서드 실행 후에 실행
    • `@Around` : 메서드 실행 전후로 원하는 대로 제어 가능
더보기
public class UserService {
    public void addUser(User user) {
        // Add the user to the database
     }
}
@Aspect
public class LoggingAspect {
    @Before("execution(* kr.ac.UserService.addUser(..)) && args(user)")
    public void logBefore(JoinPoint joinPoint, User user) {
        System.out.println("Adding user: " + user.getUsername());
    }
}

 

@Before() 내부의 코드가 실행되기 전에, 아래 logBefore 메서드 실행

 

4. PSA (Portable Service Abstraction)

  • 서비스의 인터페이스를 추상화해서 각 서비스의 변경이 발생해도 Application Code는 수정할 필요없음

 


객체 생성 방법

1. XML 형식 객체 생성

주로 싱글톤으로 관리되며, 이 경우에는 id 값을 지정하지 않아도 된다.

// XML 설정 방식
<bean id="person"
	class="kr.ac.hansung.Person"
    scope="singleton"> 
    <constructor-arg ref="developer" />  
    <constructor-arg value="John Doe" />  
    <constructor-arg value="30" />		
    <property name="myName" value="John Re" />  
</bean>
  • scope
    • singleton : 단 하나의 객체를 공유 (default)
    • prototype : 해당 빈이 주입될 때마다 새로운 객체 생성
  • <constructor-arg> : 생성자에 주입할 값
  • <property> : 세터에 주입할 값
  • value : String 값
  • ref : 다른 객체(bean)의 id 값

 

2. 어노테이션으로 객체 생성

@Component
public class PersonService {
    private Person person;

    @Autowired
    public PersonService(Person person) {
        this.person = person;
    }

    public void printPerson() {
        System.out.println("Name: " + person.getName() + 
		", Age: " + person.getAge());
    }
}
  • @Component : 빈(객체) 생성
  • @Autowired : 다른 객체를 주입할 생성자 명시
만약 new 키워드로 객체를 생성할 경우, 해당 객체는 스프링 컨테이너를 통해 관리할 수 없다.

 


스프링 컨테이너 생성 방법

1. XML 설정을 사용하는 경우

1.1 XML 설정 파일 (applicationContext.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

    <bean id="person" class="com.example.Person">
        <constructor-arg value="John Doe" />
        <constructor-arg value="30" />
    </bean>

    <bean id="personService" class="com.example.PersonService">
        <constructor-arg ref="person" />
    </bean>
</beans>

 

1.2 애플리케이션에서 컨테이너 생성 (Main.java)

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        // XML 설정 파일을 사용하여 컨테이너를 생성
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 빈(bean) 가져오기
        PersonService personService = (PersonService) context.getBean("personService");

        // 빈 사용
        personService.printPerson();
    }
}

 

ApplicationContext 인터페이스의 ClassPathXmlApplicationContext를 사용하여 XML 설정 파일(applicationContext.xml)을 읽고, 해당 설정에 정의된 빈들을 스프링 컨테이너에 등록

 

 

2. 자바 기반 설정을 사용하는 경우

2.1 자바 설정 클래스 (AppConfig.java)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example") // 해당 패키지 내 @Component가 붙은 클래스 스캔하여 빈 등록
public class AppConfig {

    @Bean // 메서드 단위로 빈 등록 가능
    public Person person() {
        return new Person("John Doe", 30);
    }

    @Bean
    public PersonService personService() {
        return new PersonService(person());
    }
}

 

2.2 애플리케이션에서 컨테이너 생성 (Main.java)

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 자바 설정 클래스를 사용하여 컨테이너를 생성
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 빈(bean) 가져오기
        PersonService personService = context.getBean(PersonService.class);

        // 빈 사용
        personService.printPerson();
    }
}

 

ApplicationContext 인터페이스의 AnnotationConfigApplicationContext를 사용하여 자바 설정 클래스(AppConfig.class)를 읽고, 그 안에 정의된 빈들을 스프링 컨테이너에 등록

 


Lombok

  • 보일러 플레이트 코드(getter/setter, 생성자 등 반복적으로 작성되는 코드)를 컴파일 시점에 자동으로 생성하여 코드의 가독성과 유지보수성 향상
  • `@getter`, `@setter`
  • `@ToString`
  • `@EqualsAndHashCode` : equals(), hashCode() 메서드를 자동 생성
  • `@NoArgsConstructor`, `@AllArgsConstructor`, `@RequireArgsConstructor`
    • `@NoArgsConstructor` : 기본 생성자 생성
    • `@AllArgsConstructor` : 모든 필드를 매개변수로 하는 생성자 생성
    • `@RequireArgsConstructor` : final 필드만 매개변수로 하는 생성자 생성
  • `@Data`
    • `@getter`, `@setter`, `@ToString`, `@EqualsAndHashCode`, `@RequireArgsConstructor`를 모두 적용
    • 테스트 용도로 주로 사용
  • `@Builder` : 빌더 패턴을 적용해 객체를 생성할 수 있다
@Builder
public class User {
    private String name;
    private int age;
}

// 사용 예시
User user = User.builder()
                .name("John")
                .age(30)
                .build();
  • `@Slf4j` : 로그를 남기기 위한 Logger 객체 자동 생성
@Slf4j
public class UserService {
    public void logMessage() {
        log.info("This is a log message");
    }
}

 


어노테이션 

  • 사용자 정의 어노테이션
    • 개발자가 필요에 따라 어노테이션 정의 가능
  • 내장 어노테이션
    • `@Override`
    • `@Deprecated`
      • 더이상 사용되지 않음을 표시
      • 해당 요소 사용 시, 컴파일 경고 발생
      • 새로운 API 사용 유도로 활용
    • `@SuppressWarnings`
      • 컴파일러 경고 무시
    • `@Require`

 

 

`@Require`

  • setter에 사용하는 어노테이션
  • 해당 세터를 호출할 때, 반드시 `<property>`를 포함하도록 강제
import org.springframework.beans.factory.annotation.Required;

public class Person {
    private String name;
    private int age;

    @Required
    public void setName(String name) {
        this.name = name;
    }

    @Required
    public void setAge(int age) {
        this.age = age;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

    <!-- Person 빈 정의 -->
    <bean id="person" class="com.example.Person">
        <property name="name" value="John Doe" />   <!-- 필수!! -->
        <property name="age" value="30" />	<!-- 필수!! -->
    </bean>

</beans>

 

 

'언어, 프레임워크 > Spring' 카테고리의 다른 글

요청(Request) 데이터 전달 방식  (0) 2025.03.20
Spring Annotation (+Request Mapping)  (0) 2025.03.19
Spring MVC  (0) 2025.03.19
WAS / Servlet / SSR, CSR  (0) 2025.03.19
HTTP, RESTful API 알아보기  (0) 2025.03.17