개발자 끄적끄적

Dependecy Injection, Spring Annotation 본문

웹프레임워크

Dependecy Injection, Spring Annotation

햏치 2024. 3. 13. 13:47

<의존성 주입(Dependency Injection)>
- 객체와 객체사이의 의존성(Object Dependencies)
ex) public class PetOwner{
      private AnimalType animal;
 
 public PetOwner( ){
 this.animal = new Dog( );
  }
}
-> Tight coupling(Dog와 PerOwner사이) => 기존방식

<Dependency Injection>
1. Bean : 객체(creates beans)
2. Performs dependency injection
  - 설정파일 : XML Config

3. Design pattern이며 framework(=Spring Container)가 주입을 시켜준다
4. Reduces coupling(객체와 객체사이의 결합도를 약하게 해준다)
  Runtime시에 의존성을 주입시켜준다(=Dyanmically injected by the framework)

ex) 객체-객체의 약한 결합, 생성자를 통해 주입
public class PetOwner{
  private AnimalType animal;
  
  public PetOwner(AnimalType animal){ //animal 생성자 인자
    this.animal =  animal;
  } 
}

//Spring Container
public class Dog{
  implements AnimalType{
...
  }
}

//Spring Container
public class Cat{
  implements AnimalType{
...
  }
}

<의존성 주입은 언제쓰이나?>
- Test(Unit Test, Integration Test)할 때 유용
- Client(=Browser)에서 request를  보내면 Controller(Isolation)가 받는다
  MyService를 호출 ,MyService(객체 로직 : External API, Database 등)
  Service Interface field가 존재 Service Interface field에 의존성 주입
  Mocked Service : 실제 서비스를 구현하지않고 MyService에 대해서 테스트, input과 output이 존재, Unit Test(단위테스트)

*Mock up : 모형물

<The Spring (IoC) Container>
- 객체를 생성 및 관리
- 객체에게 의존성을 주입

<The Spring Container 설정>
1. XML
2. Java annotations
3. Java-based Configuration

<The Spring Container 종류>
- BeanFactory
- ApplicationContext
  - ClassPathXmlApplicationContext
  - ex) ApplicationContext context = new ClassPathApplication("");
    HellWorld obj = (HelloWorld) context.getBean("helloWorld");

<Spring Container and DI>
1. main() -> ApplicationContext 생성
2. ApplicationContext -> Dog, Cat 의존성 주입
3. Injects(Cat or Dog) -> PetOwner animal

<Advantages of DI>
- Reduced Dependencies(의존성을 줄일 수 있다)
  - 코드의 변경사항 최소

- More Reusable Code
  - 코드 재사용성 가능

- More Testable Code
  - 다양한 주입을 통해 Test가 쉬워진다

- More Readable Code
  - 코드와 설정이 분리가 되어있어 가독성이 높아진다


<What are Beans?>
- POJO's(Plain old java object)를 'bean'이라 부른다
- bean은 Spring Container에 의해 생성되고 관리한다
- configuration metadata(ex. XML file)에 의해 bean이 생성
- Configuration Metadata -> Spring IoC Container -> (bean) -> Application
   bean에 접근하고 싶으면 getBean("BeanName")



<Spring Bean Definition>
- Key attributes
  - class(required) : fully qualified java class name
  - id : the unique identifier for this bean
  - scope : the scope of the objects(sigleton(=class의 객체가 한 개), prototype(=class의 객체가 다수))
  - constructor-arg : arguments to pass to the constructor at creation time //생성자의 인자를 넘겨줄 수 있다
  - property : arguments to pass to the setters at creation time //setter에 넘겨줄 인자
  - init, destory method



<Spring Bean Scope>
1. singletone : Single instance of bean in every getBean() call [Default]
  - Singletone (e.g., <bean scope="singleton" .../>)
  - 'singleton' 은 Spring container에서 단 한번 만들어진다
     Container가 shuts down 될 때 까지는 항상 동일한 bean이 제공되어진다
  
2. prototype : New instance of bean in every getBean() call
  - Prototype(e.g., <bean scope="prototype" .../>)
  - 'prototype'은 참조할 때마다 항상 새로운 객체가 만들어지며 일반적으로 더이상 객체에 대한 reference가 없을 때 사라진다

3. request : Single instance of bean per HTTP request
4. session : Single instance of bean per HTTP session
5. global-session : Single instance of bean per global HTTP session


<의존성 주입 방법(Dependency Injection Methods)>
1. Constructor-based Injection //생성자를 통해서(constructor-arg)
  - Pass dependencies in via "constructor"

2. Setter-based Injection //setter를 통해서(property)
  - Pass dependencies in via "property setters"



<Spring Annotation(주석)>
- Spring ver 2.5부터 지원
- "Old wine in new bottle" : xml의 대안으로 사용, bean과 bean을 연결(의존성 주입)
- bean configuration을 "component class"에 설정한다
- XML이 설정이 많기 때문에 Spring Annotation이 나왔다 -> Annotation minimizes the XML configuration
- Not enable by default(need explict enabling) -> 명시적으로 Spring Annotation을 enable시켜줘야한다 
- XML을 annotation을 override -> XML이 적용된다
- IDE support(IDE를 지원), 자동완성 기능



1. @Required 
- the bean property must be populated in XML configuration file
- 적용 : only setter methods
ex) 

public class boy{
private String name;
private int age;

@Required //Name에 대한 property가 존재해야한다 
public void setName(String name){
  this.name = name;
}

@Required //Age에 대한 property가 존재해야한다 
public void setAge(int age){
  this.age = age;
}
// getters ...
}

-- XML --
ex) Values by name

<bean id="boy" class="Boy">
  <property name="name" value="Rony"/>
  <property name="age" value="10"/>
</bean>


ex) Strict checking
<bean id="boy" class="Boy">
  <property name="name" value="Rony"/>
</bean>
-> Propery 'age' is requied for bean 'boy'



2. @Autowired
-적용 : methods, fields, and constructor
- No setter needed, No property needed
- wiring by type
- Singleton

ex)
public class Boy{
private String name;
private int age;

//getters and setters..
}

public class College{

@Autowired
private Boy student; //field에 적용, Boy는 bean

}

-- XML --
<bean id = "boy" class="Boy"> //Signleton
  <property name="name" value="Rony"/>
  <property name="age" value="10"/>
</bean>

<bean id="college" class="Collage">
</bean>


3. @Qualifier
ex)

public class Boy{
private String name;
private int age;

//getters and setters..
}

public class College{

@Autowired
@Qualifier(value="tony") //Boy라는 타입이 2개가 있을 때 명시해주는 것
private Boy student; 

//getters ..
}

--- XML --- 
//Two beans for "Boy" type

<bean id="boy1" class="Boy">
  <qualifier value="rony"/>
  <property name="name" value="Rony"/>
  <property name="age" vlaue="10"/>
</bean>

<bean id="boy2" class="Boy">
  <qualifier value="tony/>
  <property name="name" value="Tony"/>
  <property name="age" value="8"/>
</bean>

<bean id="collage" class="Collage">
</bean>


4. @Resource
- @Resource(name="<beanName>") is used for auto wiring by "name"
- @Resource can be applied in field, argument and methods
- Note : @Autowired and @Resource work equally well(@Autowired, @Resource는 동일하 기능을 수행한다)
  (@Resoucce : auto-wird by name, @Autowired : auto-wire by type)

ex)

public class Collage{

@Resource(name="boy1")
private Boy student;

//getters and setters...
}

--- XML ---
<bean id="boy1" class="Boy">
  <qualifier value="rony"/>
  <property name="name" value="Rony"/>
  <property name="age" vlaue="10"/>
</bean>

<bean id="boy2" class="Boy">
  <qualifier value="tony/>
  <property name="name" value="Tony"/>
  <property name="age" value="8"/>
</bean>

<bean id="collage" class="Collage">
</bean>

'웹프레임워크' 카테고리의 다른 글

Spring WebForm  (0) 2024.04.23
Spring MVC  (0) 2024.04.23
DI(Dependency Injection)  (0) 2024.04.23