개발자 끄적끄적
DI(Dependency Injection) 본문
<Spring Bean>
- Spring의 DI Container에 의해 관리되는 POJO(Plain Old Java Object)를 Bean이라 부른다
- POFO는 Spring 애플리케이션을 구성하는 핵심 객체
- Spring Ioc Container 또는 DI 컨테이너에 의해 생성 및 관리
<@Bean>
- 메소드 레벨에서 선언하며, 반환되는 객체(인스턴스)를 개발자가 수동으로 빈으로 등록
- 메소드에서 사용, 즉 메소드 이름으로 빈 이름이 결정
- 개발자가 컨트롤이 불가능한 외부 라이으버리 사용 시 사용
- ex)
@Configuration
public class AppConfig{
@Bean
public MemberService memberService(){
return new MemverServiceImpl();
}
}
<@Component>
- 클래스 레벨에서 선언하며, 스프링이 런타임시에 컴포넌트스캔을 하여 자동으로 빈을 찾고
등록하는 애노테이션
- 클래스에 사용
- 개발자가 직접 컨트롤이 가능한 내부 클래스에 사용
- ex)
@Component
public class Utility{
...
}
<@Configuration>
- 설정할 클래스
- @Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용하여
해당 클래스에서 Bean을 등록하고자 함을 명시
- @Bean 어노테이션은 반드시 @Configuration과 함께 사용
<@Autowired>
- 스프링 컨테이너에 등록한 빈에게 의존 관계 주입이 필요할 때, DI(의존성 주입)을 도와주는 어노테이션
- @Autowired 어노테이션이 부여된 메서드가 실행되며 필요한 인스턴스를 주입
- @Autowired는 총 3가지 방법으로 실현 가능
1. 생성자
2. 수정자(setter)
3. 필드 사용가능
- 생성자가 하나일 경우 @Autowired를 생략 가능
<DI>
- 결합도가 낮다
- ex)
@Component //자동으로 빈 등록
public class PersonService {
private Person person;
@Autowired
public PersonService(Person person) {
this.person = person;
}
public void printPerson() {
System.out.println("Name: " + person.getName() +
", Age: " + person.getAge());
}
}
<AOP(Aspect-Orientd Programming>
- 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로
각각 모듈화 하겠다는 것
- 모듈화 : 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것
- 스프링 @AOP를 사용하기 위해서 다음과 같은 의존성 추가
- ex)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- ex)
public class UserService {
public void addUser(User user) {
// Add the user to the database
}
}
//We want to log information about when the addUser method is called
- Non-AOP Approach
- ex)
public class UserService {
public void addUser(User user) {
// Log information about adding the user
System.out.println("Adding user: " + user.getUsername());
// Add the user to the database
}
}
----------------------------------------------------------------------
- AOP Approach
- ex)
@Aspect
public class LoggingAspect {
@Before("execution(* kr.ac.hansung.UserService.addUser(..)) && args(user)")
public void logBefore(JoinPoint joinPoint, User user) {
System.out.println("Adding user: " + user.getUsername());
}
}
- @Aspect는 포인트컷(Pointcut)과 어드바이스(Advise)로 구성된 어드바이저(Advisor)의 생성을 편리하게 해주는 기능을 가진 어노테이션
<용어 이해>
- Aspcet : 공통적인 기능들을 모듈화
- Target : Aspect가 적용될 대상을 의미하며 메소드, 클래스 등이 이에 해당
- Join Point : Aspect가 적용될 수 있는 시점을 의미하며 메솓 실행 전, 후 등이 될 수 있다
- Advice : Aspcet의 기능을 정의한 것으로 메서드의 실행 전,후,예외처리 발생 시 실행되는 코드
- Point cut : Advice를 적용할 메소드의 범위 지정
<주요 어노테이션>
- @Aspcet : 해당 클래스를 Aspect로 사용
- @Before : 대상 "메서드"가 실행되기 전에 Advice 실행
- @AfterReturning : 대상 "메서드"가 정상적으로 실행되고 반환된 후에 Advice를 실행
- @AfterThrowing : 대상 "메서드에서 예외가 발생"했을 때 Advice를 실행
- @After : 대상 "메서드"가 실행된 후에 Advice를 실행
- @Around : 대상 "메서드" 실행 전,후 또는 예외 발생 시에 Advice를 실행
<PSA(Portable Service Abstraction)>
- 환경의 변화와 관계 없이 일관된 방식의 기술로서의 접근 환경을 제공하는 추상화 구조
- PSA = 잘 만든 인터페이스
<Object Depenencies>
- ex)
public class PetOwner{
private AnimalType animal;
public PetOwner() {
this.animal = new Dog();
}
}
- tight couping
<DI>
- ex)
public class PetOwner{
private AnimalType animal;
public PetOwner(AnimalType animal) {
this.animal = animal;
}
}
----------------------------------------------------------------------
- Spring Container : Create the AnimalType object(Dog, Cat)
1) Dog
public class Dog
implements AnimalType{
//…
}
----------------------------------------------------------------------
2) Cat
public class Cat
implements AnimalType{
//…
}
<The Spring Container>
- The configuration metadata can be represented either by
- XML
- Java annotations
- Java-based Configuration
- Spring comes with two types of containers
- BeanFactory
- ApplicationContext
<Spring Bean Definintion>
- XML based configuration file
<!-- A simple bean definition -->
<bean id="..." class="...">
</bean>
<!-- A bean definition with scope-->
<bean id="..." class="..." scope="singleton">
</bean>
<!-- A bean definition with property -->
<bean id="..." class="...">
<property name="message" value="Hello World!"/>
</bean>
<!-- A bean definition with initialization method -->
<bean id="..." class="..." init-method="...“ >
</bean>
<Spring Bean의 구성요소>
- Class : Bean으로 등록할 JAVA 클래스
- id : Bean의 고유 식별자
- scope : Bean을 생성하기 위한 방법(ex. singleton, prototype 등)
- constructor-arg : Bean 생성 시 생성자에 전달할 파라미터
- property : Bean 생성 시 setter에 전달할 인수
<Spring Bean Scope>
- singletone : Single instace of bean in every getBean() call [default]
- A ‘singleton’ bean is created once in the Spring container.
This ‘singleton’ bean is given every time when referred.
It is garbage collected when the container shuts down
- prototype : New instance of bean in every getBean() call
- A ‘prototype’ bean means a new object in every request.
It is garbage collected in the normal way, i.e.,
when there is no reference for this object
- request : Single instance of bean per HTTP request
- session : Single instance of bean per HTTP session
- global-session : Single instance of bean per global HTTP session
*requst, session, global-session : Valid in the context of web-aware 'ApplicationContext'
<Dependency Injection Methods>
- Constructor-based Injection : Pass dependencies in via 'constructor'
- ex)
<bean id="petOwner" class="kr.ac.hansung.spring.PetOwner" >
<constructor-arg ref ="dog" />
</bean>
----------------------------------------------------------------------
public class PetOwner {
public AnimalType animal;
public PetOwner(AnimalType animal) {
this.animal = animal;
}
…
}
- Setter-based Injection : Pass dependencies in via property setters
- ex)
<bean id="petOwner" class="kr.ac.hansung.spring.PetOwner">
<property name="animal" ref="dog" />
</bean>
----------------------------------------------------------------------
public class PetOwner {
public AnimalType animal;
public void setAnimal(AnimalType animal) {
this.animal = animal;
}
…
}
<@Required>
- 반드시 주입해야 할 property를 설정해주는 어노테이션
- POJO 클래스의 setter 메소드에 @Required를 설정해주면 필드 데이터는 null이면 안되고,
무조건 setter를 이용하여 값을 주입해주어야한다
<@Qualifier>
- 빈은 추가 구분자를 붙여주는 방법으로 생성자에서 해당 구분자를 명시하면 그 구분자를 가진 빈을 명시
<@Autowired와 @Resource의 차이점>
- @Autowired : 클래스로 Bean을 지정(생성자/필드/메서드에 모두 적용 가능)
- @Resource : Name으로 Bean을 지정(필드/메서드에서만 적용 가능)
*@Autowired 어노테이션 타입을 이용해서 의존성을 주입한다면,
@Resource는 빈 이름을 사용해서 의존성을 주입한다
- ex) sqlSession은 SqlSessionTemplate 클래스에 의존성을 가지게 된다
@Repository
public class CommonDao {
@Autowired
private SqlSessionTemplate sqlSession;
}
- ex)sqlSession은 BlueSqlSessionTemplate의 이름을 가진 Bean 객체에 의존성을 가지게 된다
@Repository
public class TestDao {
@Resource(name="BlueSqlSessionTemplate")
private SqlSessionTemplate sqlSession;
}
'웹프레임워크' 카테고리의 다른 글
Spring WebForm (0) | 2024.04.23 |
---|---|
Spring MVC (0) | 2024.04.23 |
Dependecy Injection, Spring Annotation (0) | 2024.03.13 |