프로그램의 제어 프름을 직접 제어하는 것이 아닌 외부(스프링 컨테이너 || IoC 컨테이너)에서 관리하는 것을 말한다.
ex) 직장에 차를 몰고 가는데 내가 차를 제어하는 것이 아닌 운전 기사를 고용하는 것.
객체의 관리를 컨테이너에 맡겨 제어권이 넘어간 것.
제어의 역전을 통해 DI, AOP 등이 가능해진다. 그래서 스프링을 사용하면 객체의 제어권을 컨테이너로 넘기기 때문에 개발자는 비즈니스 로직을 작성하는 데 더 집중할 수 있다.
Container 가 Bean을 직접 주입해주는 것.
사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식.
과거 Spring에서는 필요 객체들을 개발자가 개발한 뒤, XML을 통해 일일히 Bean을 등록했다.
현재 Spring에서는 @Container, @Repository 등의 지정으로 Bean을 등록한다.
생성자 주입 : 생성한 객체 인스턴스의 참조를 생성자를 통해서 주입(연결)해준다.
class MyClass {
MyService service;
@Autowired
public MyClass(MyService service) {
this.service = service
}
public void test() {
service.test()
}
}
참고
위처럼 하나만 생성된 생성자일 때는 @Autowired가 생략이 가능하다고 함.
실제 현업에서는 final과 @RequiredArgConstructor를 사용.
// 생성자 2. 실제 현업에서 사용하는 코드
@RequiredArgConstructor
class MyClass {
private final MyService service;
public void test() {
service.test()
}
}
☪ 생성자 주입을 선택하는 이유 : 프레임워크에 의존하지 않고, 순수한 자바 언어의 특징을 잘 살리는 방법이기 때문
이외에 필드 주입과 수정자 주입이 있음.
하지만 사용을 거의 하지 않기 때문에 생성자 주입에 집중!!
외장 톰캣 필요하고 WAR를 생성한다. WAR는 자바가 읽을 수 없다.
Spring에서는 개발자가 직접 설정 파일을 작성하여 스프링 컨테이너를 구성하고, 필요한 빈 객체를 등록하고, 빈 객체 간의 의존성을 설정해야 한다.
Spring boot는 모든 설정 파일들, 모든 내가 필요한 라이브러리들을 제공해줌.
내장 톰캣 있고 JAR생성한다.
Spring boot는 스프링 프레임워크를 보다 쉽게 사용할 수 있도록 만든 프레임워크다. 개발자가 설정 파일을 작성할 필요 없이, 프로젝트의 설정과 라이브러리 의존성을 자동으로 처리해주는 기능을 제공한다.
자바 빈이 갖추어야 할 equals, hashCode를 생성.
public class User {
private Integer Id;
}
@EqualsAndHashCode(callSuper = true)
public class Member extends User {
private String name;
private String email;
}
Member member1 = new Member();
member1.setId(1);
member1.setName("A");
member1.setEmail("A@naver.com");
Member member2 = new Member();
member2.setId(2);
member2.setName("A");
member2.setEmail("A@naver.com");
@EqualsAndHashCode(callSuper = true) 일때, ID 가 다르면 다른 것.
@EqualsAndHashCode(callSuper = false) 일때, ID 가 달라도 이외 값들이 같으면 같은 것.
Java Bean은 자바로 작성된 객체로, 데이터 표현을 목적으로 한다. 그래서 getter/setter 메서드, 생성자를 가지는 클래스를 뜻한다.
다음과 같이 DTO, VO 같은 형태의 클래스를 Java Bean이라고 함.
public class AboutJavaBean {
// 필드는 private로 선언
private String bean;
private int beanValue;
// 전달 인자가 없는(no-argument) 생성자
public AboutJavaBean() {
}
// getter
public String getBean() {
return beanName;
}
// setter
public void setBean(String bean) {
this.bean = bean;
}
public int getBeanValue() {
return beanValue;
}
public void setBeanValue(int beanValue) {
this.beanValue = beanValue;
}
}
Spring Bean은 스프링 IoC 컨테이너가 관리하는 Java 객체를 의미한다.
스프링 컨테이너에 등록되어 생명주기가 관리된다.
Spring Bean은 의존성 주입을 통해 애플리케이션의 설정과 의존 관계를 관리하는 데 사용된다.
즉, 개발자가 관리하는 객체가 아닌 스프링에게 제어권을 넘긴 객체를 스프링에서 Bean이라고 부른다.
@Bean과 같은 경우에는 외부 라이브러리를 Bean으로 등록할 때 사용된다.

@Target이 METHOD로 지정되어 있으므로 메서드 위에 선언해야 한다는 뜻.
외부 라이브러리를 Bean으로 등록할 때 사용한다는 것은 외부 라이브러리는 ReadOnly File로 @Component를 선언해 줄 수 없다. 즉 개발자가 직접 컨트롤 불가.
그래서 개발자가 외부 라이브러리를 Bean으로 등록해야 한다면 인스턴스를 생성하는 메서드를 만든 후, 그 메서드에 @Bean을 선언해 Bean으로 등록해야 한다.

@Component
클래스 위에 선언 가능하고, 직접 컨트롤이 가능한 객체에서 사용된다.

@Target이 TYPE. 즉 Class Type 혹은 Interface Type, Enum Type 등에 선언할 수 있다.
@Service, @Repository, @Controller 에도 모두 @Component가 들어가 있다.
@Component는 개발자가 직접 작성한 클래스를 Spring의 Bean으로 등록하고자 할 때 사용됨.
그러면 Spring 컨테이너가 해당 클래스의 인스턴스를 Bean으로 관리할 수 있게 됨.
@ComponentScan은 @Component가 붙은 클래스들을 스캔하여 Spring 컨테이너에 Bean으로 등록하도록 해줌. 그래서 @Component로 등록된 클래스들을 자동으로 찾아내어 Bean으로 만드는 역할을 함.
즉 Spring에서 제공하는 클래스 뿐만 아니라 개발자가 직접 작성한 클래스 중 @Component가 붙은 클래스도 모두 스캔 대상이 된다.
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig{}
이렇게 해주면 빼줄 수 있다.
🔗 책
🔗 https://www.inflearn.com/blogs/3315
🔗 https://www.javaguides.net/2023/08/java-bean-vs-spring-bean.html - 자바 가이드(자바 빈 대 스프링 빈)
🔗 https://jjingho.tistory.com/10 - Java Bean VS Spring Bean
🔗 https://jjingho.tistory.com/11 - @Bean과 @Component