티스토리 뷰
728x90
반응형
FilterRegistrationBean를 이용해서 접속 ip를 체크하는 filter를 추가하였습니다.
해당 Filter 메소드에서 Service를 통해 ip를 조회해야했지만
Filter class 안에 선언했던 @Autowired가 null 값으로 나오는 이슈가 발생하였습니다.
java.lang.NullPointerException: Cannot invoke "cashnamu.cashnamu_v2.www.auth.admin.service.AllowIpService.selectAllowIpList(cashnamu.cashnamu_v2.www.auth.admin.dto.AllowIpDefaultlDTO)" because "this.allowIpService" is null
이슈 원인 코드
TestFilter 클래스
public class TestFilter implements Filter{
@Autowired
private AllowIpService allowIpService; //접속 정보 체크를 위한 Service
@Override
public void init(FilterConfig fConfig) throws ServletException {
Filter.super.init(fConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
AllowIpDefaultlDTO searchDTO = new AllowIpDefaultlDTO();
searchDTO.setSize(9999999);
List<AllowIpDTO> list = allowIpService.selectAllowIpList(searchDTO).toList();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
FiltersConfig 클래스
@Configuration
public class FiltersConfig {
...
@Bean
public FilterRegistrationBean<TestFilter> testFilter2(){
FilterRegistrationBean<TestFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TestFilter());
registrationBean.addUrlPatterns("/mgn/*");
registrationBean.setOrder(2);
registrationBean.setName("test-filter");
return registrationBean;
}
...
}
위와 같이 TestFilter @Autowired로 AllowIpService 선언하였고 FiltersConfig 안에 TestFilter에 대한 Filter 설정을 하였습니다.
실행 결과 AllowIpService 는 null 값 이슈가 발생하게 되었는데 이것은 기본적인 DI(의존성 주입) 구조에 대한 개념을 얼마나 이해했는지를 알려주는부분 입니다.
@Autowired 기본 정의
@Autowired 는 필요한 객체의 타입을 선언된 bean에서 찾아 주입을 한다.
그리고 @Autowired는 required 가 true 이다 bean이 반드시 있어야한다는 조건이 default 인데
해당 bean이 없다면 에러가 발생한다.
기본적으로 xml로 bean을 선언하지 않고 어노테이션으로 bean을 선언하기 위한 방법은 두가지 방법이 있다
첫번째 class 전체를 bean으로 선언하여 사용하는 것 그리고 클래스안에 메소드를 bean으로 선언하는 방법이다.
좀 더 세세하게 본다면
1.class 전체를 bean으로 선언하는 방식에는
@Component , @Controller , @Service , @Repository 가 해당한다.
2.메소드에 선언하는 방식에는 @Configuration이 있다.
아까 말했다시피 결국 @Autowired는 bean으로 등록된 대상을 기준으로 찾아서 열어준다 의존성이 주입이 되어져있는 경우에만 서로 연결되어 찾을 수 있다는 것이다.
그러나 TestFilter 같은 경우 현재 그 어떤 bean을 선언한다는 어노테이션이 선언되어있지 않다.
그리고 FiltersConfig 클래스 안에 testFilter2를 보게되면
FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TestFilter());
TestFilter 는 new로 생성이 된다. 그리고 TestFilter는 bean으로 선언되어 있지 않다.
그렇기 때문에 해당 TestFilter 안에
@Autowired
private AllowIpService allowIpService 로 선언하였다 할지라도 결국 찾지를 못해 null을 반환한다.
그렇다면 어떻게 사용하면 될까?
@Autowried를 이용하기 위한 방법
TestFilter
public class TestFilter implements Filter{
private final AllowIpService allowIpService;
public TestFilter(AllowIpService allowIpService) {
this.allowIpService = allowIpService;
}
@Override
public void init(FilterConfig fConfig) throws ServletException {
Filter.super.init(fConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("@@@@@@@@@@@@");
try {
AllowIpDefaultlDTO searchDTO = new AllowIpDefaultlDTO();
searchDTO.setSize(9999999);
List<AllowIpDTO> list = allowIpService.selectAllowIpList(searchDTO).toList();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
@FiltersConfig
@Configuration
public class FiltersConfig {
...
@Autowired
private AllowIpService allowIpService;
@Bean
public FilterRegistrationBean<TestFilter> testFilter2(){
FilterRegistrationBean<TestFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TestFilter(allowIpService));
registrationBean.addUrlPatterns("/mgn/*");
registrationBean.setOrder(2);
registrationBean.setName("test-filter");
return registrationBean;
}
...
}
TestFilter에서 사용하기 위해서는 외부를 통해 직접 생성자 주입하여 처리하는 방식으로 가야한다.
위에서 얘기했다시피 TestFIlter는 일반 클래스이지 bean으로 선언된 클래스가 아니기 때문이다.
그러므로 외부로부터 해당 service를 주입 받아 사용한다.
FiltersConfig는 보기와 같이 @Configuration으로 선언되어 있다. 그러므로 AllowIpService를 선언하여 사용할 수 있다.
registrationBean.setFilter(new TestFilter(allowIpService));
setFilter에서 new TestFilter를 선언하여 사용하기 때문에 해당 부분에 대한 생성자 주입을 통해 처리를 하게 된다면 제대로 작동하게 된다.
참고자료
728x90
반응형
'프로그램 언어 > Spring' 카테고리의 다른 글
Spring boot 3.x.x 에서의 Swagger적용 방법 (gradle 기준) (1) | 2023.11.28 |
---|---|
Rest API 요청 시 PKIX path build failed 에러 발생관련 이슈 처리 방법(경험담 포함..) (0) | 2023.05.29 |
Srping(boot) Filter 설정 방법 (0) | 2023.05.12 |
ThymeleafParser를 이용한 동적 pdf 파일 생성 (0) | 2023.05.03 |
Spring Post/Get 한글 파라미터 값 깨짐 현상 (0) | 2023.05.02 |
250x250
반응형
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 캐시
- 리눅스
- 네이버 클라우드
- leatcode
- ncp
- 캘린더
- hazelcast
- insert
- centos7
- docker
- 정의
- spring
- Java
- 도커
- 격리수준
- Lock
- mybatis
- Linux
- Cache
- 개념 이해하기
- 이미지
- LocalDate
- Quartz
- 알고리즘
- 컨테이너
- dfs
- dockerfile
- 권한
- MySQL
- 스케줄러
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함