티스토리 뷰

Spring

[Spring] Annotation

PeonyF 2023. 3. 7. 23:44
반응형

@Controller 

Spring MVC에서 컨트롤러를 선언하는데 사용됩니다.

Spring Framework에서 해당 클래스를 컨트롤러로 인식하고, DispatcherServlet이 요청을 받으면 
해당 컨트롤러를 호출한다. 이때, @RequestMapping을 사용하여 요청 URL과 컨트롤러 메서드를 매핑시킨다.

특징

  1. 해당 Annotation이 선언된 클래스는 Spring이 관리하는 Bean으로 등록됩니다.
  2. @RequestMapping이 선언된 메서드는 요청 URL과 매핑되며, 해당 URL로 요청이 들어오면 해당 메서드가 호출됩니다.
  3. 컨트롤러 메서드에서는 비즈니스 로직을 수행하고, 결과를 Model객체에 담아 View에 전달합니다.
  4.  View는 결과를 사용자에게 출력하는 역할을 수행한다.

 

*비지니스 로직이란?

애플리케이션에서 실제로 수행하는 중요한 업무처리. 주로 Service계층에서 사용함

ex. 은행 어플리케이션 -> 계좌개설, 입금,출금,이체등 업무가 모두 비즈니스 로직

 

*왜 결과를 Model에 담는가?

- Controller와 View 사이의 데이터 전달이 편리 (View에서 Model 객체를 사용하여 데이터를 출력 가능)

- Model 객체를 사용하면 다양한 타입의 데이터를 전달가능

- Model 객체를 사용하면 View와의 결합도가 낮아짐

 

 

@Service

Spring에서 비즈니스 로직이 구현된 클래스를 선언하는데 사용됩니다.

@Service 사용하여 해당 클래스가 Service Layer에서 사용되는 클래스임을 나타내며, 
Spring에서 해당 클래스를 자동으로 Bean으로 등록하여 사용할 수 있게 함.
-> Service Layer와 Repository Layer를 분리하여 각 계층은 독립적으로 개발,테스트,유지보수 함

 

* Service Layer

애플리케이션의 비즈니스 로직을 담당하는 계층으로 비즈니스 로직을 처리함.

Controller에서는 비즈니스 로직을 담당하지 않고 요청을 받고 응답을 반환하는 역할을 수행하며,

Service Layer에서는 비즈니스 로직을 처리하는 역할을 수행합니다.

 

*왜 Bean에 등록되어야 할까?

개발자들은 객체의 생성과 의존성 주입을 직접 관리하지 않고도, Spring 프레임워크가 객체를 자동으로 생성하고 주입하는 기능을 활용할 수 있다.

 

특징

  1. @Service을 사용하여 Service Layer를 구현하면, 해당 클래스를 자동으로 Bean으로 등록할 수 있습니다.  
  2. 따라서, Controller에서 해당 클래스를 사용하려면 @Autowired을 사용하여 의존성 주입을 수행하면 됩니다.
  3. @Service은 @Component을 상속하고 있습니다. 따라서, @Service을 사용하면 해당 클래스는 Component로 등록되며, Spring Framework에서 Bean으로 관리됩니다.
  4. @Service은 Controller와 Repository Layer 사이에서 사용됩니다. Controller에서 요청을 받으면, Service Layer에서 비즈니스 로직을 수행하고, Repository Layer에서 데이터를 액세스하여 처리 결과를 반환합니다.

 

*자동으로 Bean으로 등록하면 뭐가 좋은가?

  1. 객체의 생성과 소멸을 Spring이 관리하기 때문에, 개발자가 객체의 생성과 소멸에 대한 로직을 작성하지 않아도 됩니다. 이로 인해 코드의 양이 줄어들고, 코드의 가독성과 유지보수성이 높아집니다.
  2. Bean으로 등록된 객체는 Spring의 IoC (Inversion of Control) 컨테이너에서 관리되기 때문에, 객체 간의 의존성 주입이 자동으로 이루어집니다. 이를 통해 객체 간의 결합도를 낮출 수 있으며, 유연한 애플리케이션을 만들 수 있습니다.
  3. Spring에서는 Bean으로 등록된 객체에 대해 다양한 기능을 제공합니다. 예를 들어, AOP (Aspect Oriented Programming)를 이용한 로깅, 트랜잭션 처리 등을 지원합니다. 이러한 기능을 사용하면 애플리케이션의 성능을 개선할 수 있습니다.
  4. Spring에서는 Bean으로 등록된 객체를 스코프에 따라 다르게 관리할 수 있습니다. 예를 들어, 요청마다 새로운 객체를 생성하는 Request Scope, 세션 단위로 객체를 관리하는 Session Scope 등이 있습니다. 이를 통해 애플리케이션의 메모리 사용량을 최적화할 수 있습니다.
  5. Spring에서는 Bean으로 등록된 객체에 대해 테스트 코드를 작성하기 쉽습니다. 스프링은 테스트에 필요한 Bean을 쉽게 만들 수 있도록 지원합니다. 이를 통해 테스트 코드의 작성과 유지보수가 용이해집니다.

 

@Autowired

Spring에서 자동으로 필요한 의존성을 주입하는데 사용됩니다.

@Autowired 사용하면, 해당 객체가 스프링 컨테이너에서 자동으로 생성되고, 
의존하는 다른 객체를 자동으로 주입받음. -> 객체 간의 결합도를 낮추고, 유지보수성과 확장성을 높임

 

 

특징

  1. @Autowired을 필드에 선언하면, 해당 필드가 스프링 컨테이너에서 자동으로 생성된 빈과 연결됩니다.
  2. @Autowired을 Setter 메서드에 선언하면, 해당 Setter 메서드가 호출될 때 스프링 컨테이너에서 자동으로 생성된 빈이 해당 Setter 메서드로 주입됩니다.
  3. @Autowired을 생성자에 선언하면, 해당 생성자가 호출될 때 스프링 컨테이너에서 자동으로 생성된 빈이 해당 생성자로 주입됩니다.
  4. @Autowired을 사용하면, 스프링 컨테이너에서 객체를 생성하고, 의존성을 자동으로 주입해주므로, 개발자는 객체 생성 및 의존성 주입과 같은 부수적인 작업을 수동으로 처리하지 않아도 됩니다. 이를 통해, 코드의 가독성과 유지보수성을 향상시킬 수 있습니다.

 

*자동으로 생성된 빈과 연결된다란 뜻은?

스프링은 Bean을 생성하고, ApplicationContext에 등록한 후, 필요한 곳에서 해당 Bean을 가져다가 사용합니다.

스프링은 해당 필드의 타입에 해당하는 Bean을 ApplicationContext에서 찾아서, 필드에 주입합니다.

-> 스프링이 필요한 Bean을 자동으로 생성하고, 해당 Bean을 클래스의 필드에 주입함으로써, 개발자는 Bean을 생성하고 관리하는 코드를 작성하지 않아도 됩니다.

-> 이는 개발 시간을 단축시키고, 코드의 가독성을 높여주는 장점을 가지고 있습니다.

ex. MemberServiceImpl 클래스를MemberRepository와 의존성(Dependency)을 주입

 

*의존성을 자동으로 연결하는데 어떻게 객체 간의 결합도를 낮출까?

Spring Framework에서는 객체 간의 결합도를 낮추기 위해 Inversion of Control (IoC) 원칙을 적용

@Autowired 을 사용시

1. 스프링 컨테이너에서 객체 생성 및 관리를 담당하고, 객체 간의 의존성을 자동으로 주입

-> 코드의 가독성과 유지보수성 향상(개발자가 객체 생성과 의존성 주입에 대한 부수적인 작업을 수동으로 처리안하므로)

2. 객체 간의 의존성이 자동으로 연결되므로, 한 객체가 다른 객체에 직접적으로 의존X

-> 인터페이스나 추상 클래스를 통해 간접적으로 의존하도록 설계

-> 객체 간의 결합도를 낮춤

 

* 객체 간의 결합도

한 객체가 다른 객체에 의존하거나, 다른 객체의 내부 구조에 의존하게 되는 정도

* IoC

객체 생성과 관리를 컨테이너에게 위임하고, 객체 간의 의존성을 주입받도록 설계하는 방식

 

 

사용예시

public interface MemberService {
    void register(Member member);
    Member findById(Long memberId);
}
@Service //MemberServiceImpl 클래스를 Service Layer에 속하게 만듦
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    @Autowired //MemberRepository와 의존성(Dependency)을 주입
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Override
    public void register(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findById(Long memberId) {
        return memberRepository.findById(memberId);
    }
}
@Controller //MemberController 클래스를 Controller Layer에 속하게 만듦
public class MemberController {

    private final MemberService memberService;

    @Autowired
    // MemberController 클래스를 MemberService와 의존성(Dependency)을 주입
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

    @PostMapping("/members/new")
    public String create(MemberForm form) {
        Member member = new Member();
        member.setName(form.getName());

        memberService.register(member);

        return "redirect:/members";
    }

    @GetMapping("/members/{id}")
    public String detail(@PathVariable("id") Long memberId, Model model) {
        Member member = memberService.findById(memberId);
        model.addAttribute("member", member);

        return "members/memberDetail";
    }
}

 

@Repository

Spring에서 DAO를 구현하는 클래스를 선언하는데 사용됩니다.

데이터베이스와 관련된 역할을 수행하는 Repository Layer의 구현체임을 나타내기 위해 사용
@Autowired을 사용하여 Repository Layer와 Service Layer를 연결할 때 편리하다.
해당 클래스는 보통 데이터베이스와 직접적으로 연결되는 DAO(Data Access Object) 클래스를 구현함

 

* @Repository와 DAO와 관계

 

DAO 클래스를 Repository Layer에서 사용하게 되면, DAO 클래스의 메서드를 호출하여 데이터베이스와의 상호작용을 처리할 수 있다. 이때, Spring에서는 @Autowired 을 사용하여 Repository Layer에서 DAO 클래스를 주입할 수 있다. 이렇게 의존성 주입을 수행하면, 불필요한 코드 중복을 방지하고, 유지보수성과 생산성을 높일 수 있다.

 

@Component

Spring에서 빈으로 등록할 클래스를 선언하는데 사용됩니다.

@Component을 사용하여 클래스를 Bean으로 등록하고,
@Autowired을 사용하여 해당 Bean을 주입받아 사용하는 것이 일반적인 방법

 

*특징

@Controller, @Service, @Repository 은 @Component을 상속받는다.

 

@RequestMapping

Spring MVC에서 컨트롤러 클래스나 메서드에 URL을 매핑할 때 사용됩니다.

@Controller 어노테이션이 부착된 클래스 내부의 메서드들은 @RequestMapping 어노테이션을 사용하여 특정 URL 경로와 매핑된다.

 

* value :  매핑될 URL 경로를 지정, method : 해당 URL과 연결된 HTTP 요청 메서드를 지정

@Controller
public class HelloController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello";
    }
}

*모든 메서드들의 URL 경로에 /users가 포함될경우

@Controller
@RequestMapping("/users")
public class UserController {

    @RequestMapping("/{userId}")
    public String getUser(@PathVariable("userId") Long userId, Model model) {
        User user = userService.getUserById(userId);
        model.addAttribute("user", user);
        return "user";
    }
}

 

@PathVariable

RESTful API에서 URL 경로에서 변수 값을 추출할 때 사용

*GET 요청이 들어왔을 때 @PathVariable을 사용하여 {id}에 해당하는 값을 Long id 매개변수로 받아온다.

 -> URL 경로에서 변수 값을 추출 가능

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // id에 해당하는 사용자 정보를 조회하는 로직
        ...
    }
}

 

@RequestParam 

Spring MVC에서 HTTP 요청 파라미터를 받아올 때 사용

@RequestParam Annotation을 붙이면 해당 파라미터의 값을 받아와서 매개변수에 할당해줌

*어노테이션 내의 "id", "name", "age" 값은 HTTP 요청에서 해당 파라미터 이름과 일치해야 한다. ex. id ->id

GET /users?id=1234&name=john&age=30 HTTP/1.1
Host: example.com
@RequestMapping("/users")
public String getUser(@RequestParam("id") int id, 
                      @RequestParam("name") String name, 
                      @RequestParam("age") int age) {
    // 메서드 로직 수행
    return "user";
}

 

@ResponseBody

Spring MVC에서 HTTP 응답 본문을 직접 작성하는데 사용됩니다.

Spring의 컨트롤러 메서드는 View를 반환하는데, @ResponseBody 어노테이션을 사용하면 View 대신 컨트롤러 메서드의 반환 값 자체를 HTTP 응답 본문으로 반환합니다.

 

@GetMapping("/hello")
@ResponseBody
public String hello() {
    return "Hello World!";
}
  1. @GetMapping은 GET 요청에 대한 매핑을 처리하며,
  2. @ResponseBody는 컨트롤러 메서드에서 반환하는 문자열을 HTTP 응답의 본문으로 반환합니다.
  3.  "/hello" 요청에 대한 응답으로 "Hello World!" 문자열이 출력

 

@Configuration

스프링에서 빈(bean)을 정의하고 구성 클래스(configuration class)로 설정

@Configuration 어노테이션을 사용하여 구성 클래스를 정의하면 스프링 컨테이너가 해당 클래스를 자동으로 스캔하여 빈으로 등록합니다. 이후에는 해당 빈을 @Autowired 어노테이션을 사용하여 다른 빈에서 의존성 주입(Dependency Injection)할 수 있습니다.

 

*다른 클래스에서 myService()myRepository() 메서드를 @Autowired 어노테이션을 사용하여 해당 Bean을 주입받아 사용할 수 있다.

@Configuration
public class AppConfig {

   @Bean
   public MyService myService() {
       return new MyServiceImpl();
   }

   @Bean
   public MyRepository myRepository() {
       return new MyRepositoryImpl();
   }

}

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함