백엔드/Spring

[ Spring / 스프링 ] Annotation(어노테이션) 공부 - 1

  1. @Component : 스프링에서 해당 java파일을 관리할 수 있도록 지정하는 어노테이션
    -> Component를 지정한 파일은 @Autowired로 객체를 주입 받을 수 있다.
    -> @Component를 사용해서 주입받을 수 있지만, 페이지 역활에 따라 @Controller, @Service, @Repository로 구분하는 것을 권장한다고 한다. 
    @Component
    public class UserDaoJdbc implements UserDao{
    ...
    }

  2. @ComponentScan: 프로젝트 내의 특정 패키지 아래에서 @Component 어노테이션이 달린 클래스를 찾는다.
    -> basePackages 엘리먼트는 @Component가 붙은 클래스를 스캔할 기준 패키지를 지정할때 사용된다.
    @ComponentScan(basePackages = "user")
    public class TestApplicationContext {
    ....
    }
  3. @Transactional
    -> 프링에서는 트랜잭션 처리를 지원하는데 그중 어노테이션 방식으로 @Transactional을 선언하여 사용하는 방법이 일반적이며, 선언적 트랜잭션이라 부른다.
    @Transactional
    class UserDaoTest {
    ....​

  4. @ControllerAdvice, @RestControllerAdvice
    -> 컨트롤러에 전역으로 감시하는 역할, 대표적으로 Exception처리를 전역으로 처리할 때 사용
        @ControllerAdvice는 화면을 리턴해주는 컨트롤러에서 사용(jsp, html, 등)
        @RestControllerAdvice는 Rest Api용도에 컨트롤러에서 사용
    4.1 속성
       - basePackageClasses: 적용 클래스에만 적용
       - basePackages:  적용 패키지에 모두 적용
    @RestControllerAdvice //전역
    
    @RestControllerAdvice(basePackageClasses = ApiController.class) //해당 클래스
    
    @RestControllerAdvice(basePackages = "com.example") //지정 패키지내에 모두 적용


  5. @ResponseBody

  6. @ResponseStatus

  7. @ExceptionHandler
    -> Exception이 발생할 때 @ExceptionHandler가 존재하면, 해당 메소드를 실행
    같이 자주 사용하는 어노테이션은 @ControllerAdvice, @RestControllerAdvice

    * 우선 순위는 class > advice
    @RestController
    @RequestMapping("/api/user")
    public class ApiController {
    	@ExceptionHandler(value = MethodArgumentNotValidException.class)
    	public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e){
    		...
    	}
    }​
    - class에 @EceptionHandler -- @RestControllerAdvice(전역 적용)에 @EceptionHandler -
  8. @RestControllerAdvice(basePackages = "com.example") public class GlobalControllerAdvice { @ExceptionHandler(value = MethodArgumentNotValidException.class) public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e){ ... } }
  9. @Valid
    -> POJO Java Class의 검증

  10. @PathVariable

  11. @RequestBody
    -> Http Body를 Parsing 맵핑

  12. @RequestParam
    -> URL Query Parameter 맵핑
    11.1 속성
    1. required: 값이 없어도 실행이 가능하도록 해준다. (없으면 null로 들어온다.)
    @RestController
    @RequestMapping("/api")
    public class ApiController {
    
        @GetMapping("")
        public User get(@RequestParam(required = false) String name, @RequestParam(required = false) Integer age){
            User user = new User();
            user.setName(name);
            user.setAge(age);
            return user;
        }
    }​


  13. @CrossOrigin

  14. @ImportResource
    -> 자바클래스로 만들어진 DI 설정정보(@Configuration)에서 XML의 설정정보를 가져올 수 있게 해준다.
    -> 자바에서 작성한 DI설정과 XML에서 설정한 DI정보가 합쳐져서 설정정보가 통합된다.
    @Configuration
    @ImportResource("/test-applicationContext.xml")
    public class TestApplicationContext {
    ....
    }​
  15. @Configuration
    -> xml이 아닌 자바로 Ioc를 위한 @Bean설정을 하고 싶을때 사용
    -> @Configuration을 사용하면 xml에선 필요했던 <context:annotation-config />과 같은 설정은 할 필요가 없다.
    @Configuration
    public class DaoFactory {
    
    @Bean
    public UserDaoJdbc userDao(){
    ....
    
  16. @Bean
    -> Spring IoC(Inversion of Controll) Container가 관리하는 자바 객체를 의미
    -> 스프링에서 Bean은 싱글톤으로 존재하며, 필요할시 Spring IoC Container를 통해 주입받을 수 있다. 
        (개발자가 new를 통해 객체를 만드는 것이 아닌 메모리상에 올라가있는 객체를 받아서 쓴다.)
    @Configuration
    public class TestApplicationContext {
    
        @Bean
        public DataSource dataSource(){
        	...
        }
        
        ...
    }​

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource" >
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC" />
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    
    </beans>
  17. @Resource
    -> @Autowired와 유사하게 필드에 빈을 주입받을때 사용
    -> 필드 이름을 기준으로 빈을 찾는다.

  18. @Autowired
    -> 필드에 빈을 주입받을때 사용
    -> 필드의 타입을 기준으로 빈을 찾는다.

  19. @EnableTransactionManagement
    -> @Transactional을 이용한 트랜잭션 AOP기능을 지원한다.
    -> xml에 <tx:annotation-driven />과 동일한 역할을 한다.
    @Configuration
    @EnableTransactionManagement
    public class TestApplicationContext {
    	....
    }

  20.  @Controller
    -> View를 제공하는 controller로 설정 

  21.  @RestController
    -> REST API를 제공하는 controller로 설정

  22. @Qualifier
    -> @Autowired 사용시 같은 속성에 bean이 2개 이상일때 명시적(빈의 ID)으로 사용
    public class UserServiceTest {
    
    	...
        
        @Autowired
        @Qualifier("userDao")
        UserDao userDao;
        
        ...
     }​


  23. @Repository
    -> DAO 빈을 자동등록 대상으로 만들때 사용하는 어노테이션 (@Component도 자동등록 대상으로 사용)
    DAO 기능을 제공하는 클래스에는 @Repositry 어노테이션을 권장

  24. @Service
    -> 스프링이 제공하는 빈 자동등록용 어노테이션
    비즈니스 로직을 담고 있는 서비스 계층의 빈을 구분하기 위해 사용 
    서비스 계층은 트랜잭션 경계가 되는 곳이라 @Transactional이 함께 사용되는 경우가 많다.

  25. @Import
    -> @ImportResource와 같은 역할을 한다. 자바 클래스로 된 설정정보를 가져올 때 사용
    @Import(SqlServiceContext.class)
    //@Import({SqlServiceContext.class, TestAppContext.class, ProductionAppContext.class}) //여러개인 경우
    public class AppContext {
    ...​
  26. @Profile
    -> 실행환경에 따라 빈 구성이 달라지는 경우 프로파일로 정의를 해서 만들어서 사용
    -> 일종의 필터처럼 적용
    실행 시점에 어떤 프로파일의 빈 설정을 사용할지 지정 (@ActiveProfiles 사용)
    @Configuration
    @Profile("test")
    public class TestAppContext { //테스트용 Context
    	@Bean
        public MailSender mailSender(){
            return new DummyMailSender();
        }
    }
     
    @Configuration
    @Profile("production")
    public class ProductionAppContext {
        @Bean
        public MailSender mailSender(){
            JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
            mailSender.setHost("localhost");
            return mailSender;
        }
    }​


  27.  @ActiveProfiles
    -> @Profile을 지정한 것들 중 어떤 것을 사용할 것인지 지정 
    @ExtendWith(SpringExtension.class)
    @ActiveProfiles("test")	//@Profile중 test를 사용
    @ContextConfiguration(classes = AppContext.class)
    @Transactional
    @Rollback(false)
    public class UserServiceTest {​
    ....
    ​


  28. @PropertySource
    -> DB 연결정보나 설정정보를 확장자가 .properties인 파일로 사용 (토비책 기준. 현재는 .yaml파일도 많이 쓰임)
    properties 파일키=값(db.driverClass=com.mysql.jdbc.Driver) 로 정의
    아래의 예시는 database.properties 파일이다.
    db.driverClass=com.mysql.jdbc.Driver
    db.url=jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC
    db.username=root
    db.password=root
    이런 .properties파일을 소스에서 사용하고 싶을 때 @PropertySource 어노테이션을 사용

  29. @Enable*
    -> @Import를 다른 어노테이션으로 대체.
    이렇게 썼을때의 장점 빈의 종류나 계층을 나타내기 좋다.
    AOP를 이용해 특정 어노테이션이 달린 빈만 부가기능을 제공할 수 있다.
    @Import(value = SqlServiceContext.class)
    public @interface EnableSqlService {
    }​


  30. @ServletComponentScan
    -> 필터를 특정 api에서만 적용하고 싶을때 사용한다? (좀 더 찾아서 정리해야 할 듯)
    @SpringBootApplication
    @ServletComponentScan
    public class FilterApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FilterApplication.class, args);
        }
    
    }

  31. @WebFilter
    -> 필터를 적용하고 싶은 api를 urlPatterns(String 배열)를 통해 지정하는 역할을 한다.

    @WebFilter(urlPatterns = "/api/user/*")
    public class GlobalFilter implements Filter {
    ....
    }


  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  

 

참고 도서:

토비의 스프링 3.1

 

참고 사이트:
https://goddaehee.tistory.com/167
https://www.whiteship.me/springboot-no-more-runwith/

https://namocom.tistory.com/421