SPRING FRAMEWORK

개발중 발생했던 @Autowired 관련 이슈 정리

Ambitions 2021. 1. 7. 14:22

여태까지 @Autowired 어노테이션은 의존성을 주입해주는 기능을 하는것으로 알고 있었는데, 최근 백엔드쪽 작업을 하다가 보니 A라는 클래스에서 B라는 클래스 내의 메소드의 기능을 사용하는 부분을 구현해야 했는데, 왜인지 모를 NullpointerException이 발생했었다, 대략 코드는 다음과 같이 작성했었는데,

※ Spring 의존성 주입(Dependency Injection) : 타 객체를 Spring bean을 통해 사용할 수 있게 해주는 것

(필자의 방식대로 한 줄로 정리한 내용이기때문에 그냥 그렇구나 하고 참고만 하기를 권장)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Service
@Transactional
public class Bclass {
 
    @Autowired
    private Repository repo; //dao(데이터 접근객체) @Autowired를 통해 의존성 주입
    
    public void test() {
        Aclass aclass = new Aclass(); //A클래스 객체 생성
        List<Long> val = aclass.func(); //A클래스 내 메소드 호출
        // 이후 비지니스로직
    }
}
 
//A클래스
public class Aclass {
 
    @Autowired
    private Repository2 repo2;
    
    public void func() {
        repo2.findAll();
    }
}
cs

처음에는 @Service어노테이션을 빼먹고 있어서 dao객체를 불러오지 못해 예외가 발생하는 줄 알고, @Service어노테이션을 추가해서 실행해보니 변함없이 NullpointerException발생했다. 

이후 몇시간을 검색과 고민을 하며 찾아본 결과 B클래스에서 new 연산자를 이용해서 A클래스의 메소드 호출하면 A클래스에서 @Autowired를 이용한 객체는 B클래스에서 사용하려고 할 떄 의존성을 주입받지 못한다는 것이였다.

 

즉, Bclass의 test메소드에서 Aclass func이라는 메소드를 호출했을 때 func에서 사용되는 repo2가 B클래스에서 new연산자를 이용해 호출되었을 때에는 repo2가 의존성을 주입받지 못했기 때문에 오류가 나는것 이였다.

따라서 나의 경우는 다음과 같이 코드를 변경하였다.

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
@Service
@Transactional
public class Bclass {
 
    @Autowired
    private Repository repo; //dao(데이터 접근객체) @Autowired를 통해 의존성 주입
    
    @Autowired
    private Aclass aclass; // aclass자체를 의존성주입
    
    public void test() {
        aclass.func(); // aclass의 메서드호출
        // 이후 비지니스로직
    }
}
 
 
 
//A클래스
public class Aclass {
 
    @Autowired
    private Repository2 repo2;
    
    public void func() {
        repo2.findAll();
    }
}
cs

위 주석과 같이 aclass자체에 @Autowired를 통해 의존성을 주입하니까 문제없이 잘 실행되었다.

이렇게 간단한 문제를 오랜시간 고민했다는 것이 좀 아쉽기는 했지만,  Srping DI, Spring bean등에 대해서 알아볼 수 있게되어 유익한 시간이였다고 생각한다.