springframework

@ComponentScan 의 사용. 필터링 추가, 및 제외.

Jungsoomin :) 2020. 7. 27. 00:23

@ComponentScan 에노테이션은 정말 단비같은 에노테이션이라는 것을 사용할 때마다 느끼고 또 느낀다.

 

일단, 이번기회에 Controller 공통 Advice 를 가능하게 해주는 @ControllerAdvice 에노테이션을 배우는 와중, ComponentScan의 대상으로 등록되지 않는 듯해서, 어떻게하면 ComponentScan으로 등록할수 있을까..하고 기억을 되살리는 겸 서칭과 책 정독을 시작한 것을 기억을 되살려보자.


@ControllerAdvice 에노테이션은 컨트롤러의 공통기능을 정의하는 에노테이션이며 클래스에 붙인다. , @ExceptionHandler 에노테이션을 가져 익셉션을 공통처리할 수 있게끔한다. @ExceptionHandler 에노테이션의 값처리할 Exception의 클래스를 지정한다.

 


다시 @ComponentScan 에노테이션으로 넘어와서.

  1. 포함은 includeFilters , 제외는 exculdeFilters 로 시작하며 @Filter 에노테이션의 배열[] 로 값을 갖는다.

  2. @Filter 에노테이션 속성 값으로 type 속성을 주고, FilterType의 상수값을 적용하면 해당 필터타입으로 필터링을 한다는 을 뜻한다.

  3. ANNOTATION, ASSIGNABLE_TYPE, ASPECTJ, REGEX 정도로 타입을 구분한다.

  4. 어노테이션, 어사이너블 타입은 class 속성을 가지며 class배열[]을 값으로 갖고 클래스들을 지정하여 필터링한다.

  5. 에스펙트J, 정규표현식은 pattern 속성을 가지며 String배열[]을 값으로 가지고, 정규표현식이나 ASPECTJ 문법으로 범위를 정하고 필터링한다.

ASPECTJ문법 사용의 전제조건ASPECTJWEAVER 의존이 존재해야한다는 것을 기억하며, AOP 설정에도 @Pointcut 이나 @Around 의 값으로 execution 명시자에 사용된다는 것을 기억한다. @ASPECT 어노테이션 적용클래스는 @ComponentScan의 대상이 된다..고? 기억한다.

 

ASSIGNABLE_TYPEValidator 구현객체의 support 메서드에 사용된다는 것을 기억하고 있다. Validator 사용시 support()메서드는 반드시 구현해야한다. 즉 해당타입과 그 하위타입을 일컫는 말이다.

Global Range Validator 사용시 Validator 등록 없이 검증을 하려면  Bean-Validation-api 와 Bean-Validation-Provider 의 의존이 필요하다...고 기억한다. Provider 의존으로는 Hibernate-Validator 인가..이게 Bean-Validation Provider로 사용했을 것이다.

 

검증 커멘드 객체의 필드 값에 @Email @NotEmpty @NotBlank @NotNull @Size 등의 에노테이션을 추가해서 검증 했을거고...

Controller Range Validator에는 Validator 구현객체를 @InitBinder 에노테이션이 적용된 메서드에 적용시켰을거다.

   매개변수가 WebDataBinder....의 메서드로 setValidator , addValidator 를 사용해서 Validator를 추가 하고 ,

       @Valid 에노테이션요청매핑 에노테이션이 적용된 파라미터의 커맨드 객체 앞에 두고 검증을 하여 Errors 객체에 에러 코드를                              <form:errors> 로 출력했을 거다...제대로 기억하는게 맞나 싶은데 이게...맞나. 애석하다, 잊어가는게..

 

Interceptor 구현객체 @EableWebMvc 적용 클래스이자 WebMvcConfigurer 구현객체addInterceptors 메서드 에서 addInteceptor 메서드에 Interceptor 구현객체를 설정 한후 addPathPatterns 메서드에 값으로 Ant 패턴을 준다는을 기억한다. 메서드 명이 맞나 모르겠다.

 

Ant 패턴은 * ** ? 로 경로를 표현한다.

 

기억되살리기는 여기까지하고, 본론 코드를 적어 놓는다.


여기가 핵심. @ComponentScan 에노테이션@Filter 배열로 컴포넌트 스캔 영역을 include (includeFilters) 해놓았다. 

 

필터링 타입은 ANNOTATION 이며, classes 속성에는 org.springframework.web.bind.anntation.ControllerAdvice.class 가 등됬다.

 

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.soomin.controller", "com.soomin.interceptor" }, includeFilters = {
		@Filter(type = FilterType.ANNOTATION, classes = {
				org.springframework.web.bind.annotation.ControllerAdvice.class }) })
public class WebMvcConifg implements WebMvcConfigurer {

 


 

위에 적어놓은 기억되살리기가 맞는 지 확인과정과 기억 남기기용 @EnableWebMvc 적용 클래스이자 WebMvcConfigurer 구현객체의 메서드와 설정 기제.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.soomin.controller", "com.soomin.interceptor" }, includeFilters = {
		@Filter(type = FilterType.ANNOTATION, classes = {
				org.springframework.web.bind.annotation.ControllerAdvice.class }) })
public class WebMvcConifg implements WebMvcConfigurer {

	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//		DateTimeFormatter 설정이 첫번째
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 a HH시 mm분 ss초");
		ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
				.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(formatter)).build();
//				.simpleDateFormat("yyyy년 MM월 dd일 a HH시 mm분 ss초")
		/*
		 * .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).build();
		 */

		converters.add(0, new MappingJackson2HttpMessageConverter(objectMapper));
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 인터셉터의 addPathPatterns 메서드의 경로는 Ant패턴으로 정의한다.
		registry.addInterceptor(new AuthCheckInterceptor())
				.addPathPatterns("/edit/**")/* .excludePathPatterns("edit/help/**") */;
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/views/", ".jsp");
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/main").setViewName("main");
	}

	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasename("messages.label");
		messageSource.setDefaultEncoding("UTF-8");
		return messageSource;
	}

}

'springframework' 카테고리의 다른 글

@Log4j 에노테이션 적용이 안될때...  (0) 2020.08.02
paging 기법.  (0) 2020.07.29
Multi-Thread 환경에서의 Spring Bean , ApplicationContext  (0) 2020.07.16
Servlet과 Thread-safe  (0) 2020.07.16
.do 확장자의 사용..?  (0) 2020.07.16