여기서 IoC가 잘 이해가 가지 않아 예시로 공부해 보았다. 만약, @Repository 어노테이션을 사용하면 스프링 컨테이너가 Service를 생성할 때 자동으로 repository를 주입해 준다. 아래의 코드를 보면, @Autowired부분에 해당된다.
@Repository // UserRepository를 빈으로 등록
public class UserRepository {
// UserRepository의 메서드들...
}
@Service // UserService를 빈으로 등록
public class UserService {
private final UserRepository userRepository;
@Autowired // UserRepository를 자동으로 주입
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
그러나, 다음 코드를 보면 Spring에게 의존성 주입을 명시적으로 요청하지 않았기 때문에 IoC가 발생하지 않는다.
public class UserRepository {
}
public class UserService {
private final UserRepository userRepository;
public UserService() {
this.userRepository = new UserRepository(); // 의존성 직접 생성
}
}
p1과 p2는 같은 객체를 참조하고 있으므로 같은 값이다. -> 스프링은 기본적으로 빈을 등록할 때 싱글톤으로 함
@Getter
@Setter
@ToString
@AllArgsConstructor
public class Person {
private String name;
private int age;
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="chapter01.Person">
<property name="name"> <!-- name은 private라서 값을 대입할 수 없음 -> setName 메소드를 무조건 호출할 수 밖에 없음 -->
<value>홍길동</value>
</property>
<property name="age">
<value>30</value>
</property>
</bean>
</beans>
}
}
@All~를 추가했는데 beans.xml에서 에러가 나는 이유 : 기본 생성자가 없기 때문 -> 현재의 bean은 기본 생성자를 통해 객체를 생성하는데, person에는 두 개의 생성자만 초기화 해 주고 있기 때문에 에러가 남
@NoArgsConstructor를 추가하면 해결이 된다.
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private int age;
}
여기서 이순신과 40을 바꿔 쓰면 에러가 난다. 처음 Person class에서 String, int로 적었기 때문에 타입이 달라졌기 때문이다.