🌿 스프링 애노테이션
@SpringBootApplication
⇒ 스프링 부트 어플리케이션은 Bean을 2번 등록한다. 처음에 ComponentScan으로 등록하고, 그 후에 EnableAutoConfiguration으로 추가적인 Bean들을 읽어서 등록
-
@EnableAutoConfiguration-
jar 의존성에 따라 자동적으로 스프링 애플리케이션의 환경 설정 (automatically configure)
-
AutoConfiguration은 결국 Configuration이다. 즉, Bean을 등록하는 자바 설정 파일
-
@EnableAutoConfiguration에 의해 spring.factories 안에 들어있는 수많은 자동 설정들이 조건에 따라 적용이 되어 수 많은 Bean들이 생성되고, 스프링 부트 어플리케이션이 실행
-
-
@ComponentScan: enable@Componentscan on the package where the application is located-
해당 패키지에서 @Component 어노테이션을 가진 Bean들을 스캔해서 등록하는 것이다.(@Configuration, @Repository, @Service, @Controller, @RestController 포함)
-
-
@Configuration: allow to register extra beans in the context or import additional configuration classes-
IOC container 클래스를 Bean 구성 Class
-
- @Bean vs. @Component*
: Spring(IoC Container)에 Bean 을 등록하도록 하는 메타데이터를 기입하는 어노테이션
⇒
@Component: 개발자가 직접 작성한 Class 를 Bean으로 만드는것⇒
@Bean: 개발자가 작성한 Method를 통해 반환되는 객체를 Bean으로 만드는것 -
⭐ @Bean : 개발자가 직접 제어가 불가능한 외부 라이버리등을 Bean으로 만들때 사용
@Configuration public class ApplicationConfig { @Bean(name="myarray") public ArrayList<String> array() { return new ArrayList<String>(); } } -
ArrayList와 같은 라이버리등을 Bean으로 등록하기 위해서 객체반환 메소드를 만들고 @Bean을 붙여주면 된다. -
@Bean 어노테이션에
name이라는 값에 사용하면 자신아 원하는 id 로 Bean 등록 가능 / 어노테이션 name 입력하지않을 경우 메소드의 이름 ⇒ Bean 의 id (ex.array)⭐ @Component : 개발자가 직접 작성한 class를 Bean으로 등록하기 위한 어노테이션
**@Component(value = "mystudent")** public class Student { public Student() { System.out.println("hi"); } } -
Studentclass 는 개발자가 사용하기 위해 직접 작성한 클래스/ Bean으로 등록하기 위해 상단에@Component -
@Component추가 정보가 없다면 Class의 이름을 Bean id로 사용. -
@Bean과 다르게@Component는 name 이 아닌 value를 이용해 Bean 이름 지정⭐ @Autowired : 형(타입) 을 통해 해당 자리에 들어올 객체를 판별하여 주입.
**@Component // IOC Container 에 Bean 으로 등록** public class Pencil { } **@Component(value = "mystudent")** public class Student { **@Autowired //의존성 자동 주입** private Pencil pencil; public Student() { System.out.println("hi"); } }
-
@Component를 이용한 Bean의 의존성 주입은@Autowired어노테이션 사용
⭐ @Qualifier -
@Autowired와 같이 쓰이며, 같은 타입의 빈 객체가 있을 때 해당 아이디를 적어 원하는 빈이 주입될 수 있도록 하는 애노테이션
-
해당 자리에 들어올 수 있는 객체가 여러개인 경우, 즉 다형성을 띄고 있는 객체타입에 @Autowired 를 사용할 경우에는
@Qualifier("Bean이름")을 이용하여 해당 자리에 주입될 Bean 명시
-
-
🌈🌈 ApplicationContext 와 BeanFactory
ApplicationContext는 Pre-loading을 하고 즉, 즉시 인스턴스를 만들고 BeanFactory는 lazy-loading을 하여 실제 요청 받는 시점에서 인스턴스를 만든다고 한다.
⇒ 차이점은 인스턴스화 시점이 다르다는 것
*** 특별한 이유가 없다면 BeanFactory 보다는 ApplicationContext를 써라
특별한이란 메모리 소비가 중요하거나 리소스가 제한된 장치들을 말한다. 일반적인 엔터프라이즈 어플리케이션은 ApplicationContext를 사용하는 게 낫다. 그 이유는 BeanPostProcessor 확장 포인트를 사용 할 수도 있고, 트랜잭션과 AOP와 같은 상당한 양의 지원을 받을 수 있다
⭐ ApplicationContext
: 오브젝트 생성, 관계설정, 만들어지는 방식, 자동생성, 후처리등 여러가지 일들을 한다. 또 한 BeanFactory를 상속받고 있다.
// 1. IoC 컨테이너 생성
ApplicationContext context =
new AnnotationConfigApplicationContext(**Config.class**);
// 2. Member Bean 가져오기
Member member1 = (Member) context.**getBean**("member1");
member1.print();
-
즉시 인스턴스 만듬. 구현체는
ApplicationContext이지만 실제 사용하는getBean메서드는BeanFactory인터페이스의 메서드이다 -
빈 팩토리에 여러가지 컨테이너 기능을 추가한 것 →
ApplicationContext
⭐ BeanFactory
: 설정 프레임워크와 베이직한 기능 담당 (initiates and configures bean)
💚 Spring Bean 세팅 예시
@Configuration
class AnnotationConfig {
@Bean(name = {"tiger", "kitty"})
@Scope(value = "prototype")
Tiger getTiger(String name) {
return new Tiger(name);
}
@Bean(name = "lion")
//Lion has the default singleton scope
// lion 이름의 빈 생성
Lion getLion() {
return new Lion("Hardcoded lion name");
}
interface Animal {}
}
▶️ getBean()
- 이름으로 호출하기
Object lion = context.getBean("lion");
- 이름과 타입으로 불러오기
: specify both the name and type of the requested bean
Lion lion = context.getBean("lion", Lion.class);
assertThrows(BeanNotOfRequiredTypeException.class, () ->
context.getBean("lion", Tiger.class));
}
- 타입으로 빈 불러오기
Lion lion = context.getBean(Lion.class);
assertThrows(NoUniqueBeanDefinitionException.class, () ->
context.getBean(Animal.class));
}
- 빈을 이름과 생성자 매개 변수로 불러오기
Tiger tiger = (Tiger) context.getBean("tiger", "Siberian");
Tiger secondTiger = (Tiger) context.getBean("tiger", "Striped");
assertEquals("Siberian", tiger.getName());
assertEquals("Striped", secondTiger.getName());
- 빈의 타입과 매개 변수
Tiger tiger = context.getBean(Tiger.class, "Shere Khan");
assertEquals("Shere Khan", tiger.getName())
💚 공부 예제 :
▶️ Example1Application.java
//@SpringBootApplication
public class Example1Application {
public static void main(String[] args) {
//SpringApplication.run(Example1Application.class, args);
// 1. IoC 컨테이너 생성
ApplicationContext context = new AnnotationConfigApplicationContext(**Config.class**);
// 2. Member Bean 가져오기
Member member1 = (Member) context.getBean("member1");
member1.print();
// 3. Member bean 가져오기
Member member2 = context.getBean("hello", Member.class);
// Bean id = "hello" 라는 member2 빈을 불러오기 - Member.class 존재
member2.print();
// 4. PrintB Bean 가져오기
Printer printer = context.getBean("printerB", Printer.class);
member1.setPrinter(printer);
member1.print();
// 5. 싱글톤인지 확인
// if(member1 == member2) {
// System.out.println("동일한 객체 입니다");
// } else {
// System.out.println("서로 다른 객체입니다. ")
// }
}
}
▶️ Config.java
@Configuration //어노테이션은 어노테이션기반 환경구성
public class Config {
// Bean : Spring 의 IoC방식으로 관리하는 객체
// 빈 팩토리 (Beanfactory) : 스프링의 IoC 를 담당하는 핵심 컨테이너
// 어플리케이션 컨텍스트 (applicationContext): 빈 팩토리를 확장한 IoC Container
@Bean
public Member member1() {
//Setter injection (setter메서드를 이용한 의존성 주입)
Member member1 = new Member();
member1.setName("홍길동");
member1.setNickname("도사" );
member1.setPrinter(new PrinterA());
return member1;
}
@Bean(name = "hello")
// hello 라는 이름을 가진 bean 생성
public Member member2() {
//Constructor Injection (생성자를 이용한 의존성 주입)
return new Member("전우치", "도사" , new PrinterA());
}
@Bean
public PrinterA printerA() {
return new PrinterA();
}
// 이름을 지정하지 않으면 메서드의 이름이 빈의 이름을 등록된다.
@Bean
public PrinterB printerB() {
return new PrinterB();
}
}
▶️ Member.java
public class Member {
private String name;
private String nickname;
private Printer printer;
public Member() {
}
public Member(String name, String nickname, Printer printer) {
this.name = name;
this.nickname = nickname;
this.printer = printer;
}
public void setName(String name) {
this.name = name;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setPrinter(Printer printer) {
this.printer = printer;
}
public void print() {
printer.print("Hello" + name + ":" + nickname);
}
}
▶️ Printer Interface
public interface Printer {
public void print(String message);
}
▶️ PrinterA
▶️ PrinterB
public class PrinterA implements Printer{
@Override
public void print(String message) {
System.out.println("Printer A :" + message);
}
}
public class PrinterB implements Printer{
@Override
public void print(String message) {
System.out.println("Printer B: " + message);
}
}

'🌈 Spring Framework > 🌱 Spring-boot' 카테고리의 다른 글
| Lombok 사용시 주의사항 (0) | 2021.05.03 |
|---|---|
| Validator - BindingResult (0) | 2021.02.27 |
| @SpringBootApplication (0) | 2021.02.18 |