본문 바로가기

자바

Autowired해줬는데도 NullException뜰 때 [Java, Spring Boot]

반응형

AService, BService, CService, DService가 있다고 가정해보자.

 

AService에 createList 메서드가 있고 BService에서는 AService.createList 를 이용한 getResult메서드가 있다.

BService.getResult를 CService와 DService에서 사용하고 싶을 때

 

 

AService.java

@Service
public class AService {

	public List<Map<String, String>> createList(String language) {
		List<Map<String, String>> list = new ArrayList();
		Map<String, String> map = new HashMap<>();
        
		map.put("name", "개발새발자");
		map.put("language", language);
		list.add(map);
        
		return list;
    }
}

 

BService.java

@Service
public class BService {

	@Autowired
	private AService service;

	public Map<String, Object> getResult() {
		Map<String, Object> result = new HashMap<>();
        
		result.put("list", service.createList("java"));
		result.put("resultCode", "200");
		result.put("message", "java란 무엇인가?");
        
		return result;
    }
}

 

CService.java

@Service
public class CService {

    @Autowired
    private BService service;

	public void result() {
		Map<String, Object> result = service.getResult();
        
		System.out.println(result.get("message"));
    }
}

 

DService.java

@Service
public class DService {

	public void result() {
		BService service = new BService();
		Map<String, Object> result = service.getResult();
        
		System.out.println(result.get("message"));
    }
}

 

이렇게하면 CService, DService 모두 문제없이 잘 돌아갈까?

 

아니, CService로 호출한 BService.getResult()는 문제없이 돌아가지만 DService에서 호출한 BService.getResult()는 AService가 Null이라 NullPointerException이 뜬다.

왜냐? 

BService에서 @Autowired 어노테이션을 사용해 스프링 컨테이너에서 자동으로 의존성 주입을 하도록 해놨는데, DService.java처럼 BService service = new BService();로 객체를 생성해버리면 스프링 컨테이너에서 관리하는 객체가 아니기 때문에 @Autowired를 이용한 자동 의존성 주입이 불가하기 때문에 Null이 된다.

그러니 어디에서는 정상적으로 돌아가는데 특정 메서드에서만 타고 들어올 때 NullPointerException이 뜬다면 어디선가 new로 생성하고 있는 건 아닌가 확인해보자