리루

Spring IoC / Bean 본문

#Spring

Spring IoC / Bean

뚱보리루 2019. 3. 25. 00:01

1. IoC : Inversion of Control : 의존관계 주입

 - 어떤 객체 / 클래스가 사용할 의존객체를 직접 만들어서 사용하는 것이 아니라 어떤 장치(생성자 등)를 사용해서 주입받아 사용하는 것.

 - Spring이 아니더라도 의존주입 장치가 있다면 사용할 수 있다.

 - Spring IoC 컨테이너를 사용하는 이유는 여러가지 DI 방법과 노하우가 쌓여있는 프레임워크이기 때문

 - 컨테이너 내의 객체들을 빈이라고 부른다.

 - 컨테이너에는 IoC 기능을 제공하는 기능을 가진 빈들이 들어있다.

 - 이런 빈들을 컨테이너로 부터 가져와서 사용.

 - 애노테이션 기반 개발은 구글 쥬스?가 처음 제공

 - 스프링 IoC의 가장 핵심은 BeanFactory interface이다.

 - 스프링 IoC 컨테이너는 빈 설정파일이 있어야한다.(고전적인 방법)

- application.xml 같은거 

- 주입은 property라는 태그를 사용, name, ref(다른 bean의 id)

- 일일이 xml파일에 bean 등록해주는게 번거롭다.

- 그래서 나온 대안이 컴포넌트 스캔(spring 2.5 ~ )

- <context:component-scan base-package= "me.xx.xxxx">

- 기본적으로 @Component 애노테이션을 사용해서 빈으로 등록할 수 있다.

- @Autowired 애노테이션을 사용해서 의존주입.

- Bean 설정파일을 .java 파일로 만드는 방법 등장.

- @Configuration 애노테이션 사용.


- @ComponentScan(basePackageClasses = DemoApplication.class)

: DemoApplication.class가 위치해 있는 곳부터 Component Scan 해라(Bean 등록할 애들 찾아서 등록해라)는 의미.



2. 빈 : 스프링 IoC 컨테이너가 관리하는 객체

 - @Repository, @Service 등의 애노테이션을 붙여주면 AutoScanning?을 통해 빈으로 등록되어 IoC 컨테이너가 관리한다.

 - 의존성 주입을 받으려면 Bean이 되여야된다.

 - 빈의 스코프 관리를 위해서 컨테이너로 관리되어야 한다.(싱글톤, 프로토타입 ....등)

 - 빈 객체의 기본 스코프는 싱글톤이다.

 - 빈으로 등록되면 라이프사이클 인터페이스를 지원한다.

- @PostContruct : 빈 생성직후 호출되는 라이프사이클 콜백



3. ApplicationContext

 - ApplicationContext는 BeanFactory를 상속받은 구현체이다.

 - BeanFactory로 부터 받은 IoC 컨테이너 기능 및 다른 기능들을 가짐(BeanFactory 기능)

 - 만들어 놓은 빈 설정 파일을 불러와서 사용.(고전적인 방법)

- ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

- BookService bookService = (BookService) context.getBean("bookService);

- java 파일로 생성된 빈 설정파일(개선된 방식)

- ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationContext.class);

- @SpringBootApplication 애노테이션 사용(Spring Boot 에서 지원하는 방식,)

- ApplicationContext를 사용해지 않아도 된다.

- @Configuration, @ComponentScan 이 포함되어 있는 애노테이션

- Environment 기능

- EnvironmentCapable 을 상속받은 기능

- 프로파일 : 빈들의 묶음(배포 환경에 따라 사용될 다른 빈 들의 묶음을 선택하기 위함)

- "Default" 프로파일은 기본으로 포함된다.

- @Profile("test") 이런 식으로 프로파일 이름 설정 : test라는 프로파일로 실행하지 않으면 bean 설정이 안된다.

- Profile 설정 방법은 실행시에 -Dspring.prifiles.active="test" 이런 식으로 적용

- @Profile("!prod & test") 처럼 사용할 수도 있다.(표현식 사용가능)


- Property : key, value 쌍의 특성을 읽어오는 기능

- 계층형으로 정리되어있다.

- @Autowired ApplicationContext ctx;

- Environment environenment = ctx.getEnvironment();

- environment.getProperty("app.name");

- JVM 시스템 프로퍼티 : VM 프로퍼티 사용 : Dapp.name = spring5

- app.properties 파일을 만들어 정리

@PropertySource("classpath:/app.properties")

- @Value("${app.name}") String appName; 으로 사용가능


 - MessageSource : 메시지 다국화 기능

- MessageSource라는 Interface 구현

- ResourceBundleMessageSource Bean 으로 자동 등록되어있음.

- messages.properties, messages_ko_KR.properties 생성

각각 파일에 greeting=hi {0}, greeting=안녕하세요 {0}처럼 적어줌


 - ResourceLoader : 리서스를 로딩해주는 인터페이스 상속

- @Autowired ResourceLoader resourceLoader;

- Resource resource = resourceLoader.getResource("class path:test.txt");

- resource.exists();    // resource 존재 유무 출력


 - ApplicationEventPublisher

: 옵저버 패턴을 기반으로 이벤트 처리를 위해 사용됨



4. IoC 컨테이너의 @Autowired

- 생성자를 이용한 방법

- Interface 구현체가 많은 경우(여러 개의 bean이 있기 때문에 어떤 빈이 주입되어야 할 지 모른다.)

- @Primary 애노테이션 사용.

- @Qualifier("beanName") 사용

- BeanPostProcessor에 의해서 구동 (Interface lifecycle 공부하면됨)

- Bean Initailization life cycle 이후에 부가적인 작업을 하기 위한 것.

- AutowiredAnnotationBeanPostProcessor가 @Autowired 애노테이션을 처리해주는 것.

- 처리 : 의존주입을 처리해준다.

- 언제 : BeforeInitialization (postProcessBeforeInitialization)


5. @Component, 컴포넌트 스캔

 - @ComponentScan (spring 3.1 ~)

-  해당 패키지 이하의 파일들은 모두 스캔, 해당 패키지 밖은 스캔안함



6. AOP(Aspect-oriented Programming)

- AspectJ : java 구현 AOP기능

- 흩어진 Aspect를 모듈화 할 수 있는 프로그래밍 기법(OOP와는 보완관계)

- Concern : 여러 클래스, 매소드에 걸쳐서 나타나는 비슷한 코드들(ex, Transaction, 실행시간 측정 코드)

- Aspect : 해야할 일(advice)과, 어디(target)어디에 적용할지(pointcut)를 묶어서 정의한 모듈

- joinpoint : method 실행 시점(생성자 호출할 때) 등 끼어들 수 있는 지점

- 프록시 패턴 : 프록시 객체가 원래해야할 일을 갖고있는 객체(real subject)를 감싸서 실제 클라이언트의 요청을 처리

- 프록시와 원래 객체는 같은 interface 사용

- 프록시 객체에 @Primary 애노테이션 추가(의존주입을 위함)

- 프록시 객체에는 원래해야할 일을 갖고있는 객체를 의존주입(@Autowired) 해줘야 한다.

- 프록시가 하는 일은 delegation(위임)을 하는 것이다.

- 프록시 함수에서 의존주입 받은 원래 객체의 함수 실행 + 부가적인 기능(시간 측정 등) 추가

- 목적 : 접근제어 및 부가기능 추가

- 동적 프록시 : 동적으로 프록시 객체 생성하는 방법

- 자바가 제공하는 방법은 인터페이스 기반 프록시 생성.

- CGlib는 클래스 기반 프록시도 지원

- AbstractAutoProxyCreator가 그 역할을 한다.

- BeanPostProcessor의 구현체 


- SpringAOP

- @Aspect 애노테이션 사용 +2가지 정보 필요(해야할 일 : advice , 어디에 적용할 것인가: pointcut)

- advice : ProceedingJoinPoint

- pointcut : @Around(execution(* me.xx..*.EventService.*(..))") : me.xx 패키지 내 EventService 내의 모든 매서드에 해당 행위를 적용하라.

- Annotation을 만들어서 pointcut을 지정해줄 수 도있다.(코드의 변경이 있어야한다는 단점)

- Annotation 생성 시 @Retention(RetentionPolicy.CLASS) 필요 : Annotation 정보를 어디까지 유지할 것인가.

- RetentionPolicy.CLASS : 바이트코드에 까지 남는다, .SOURCE는 컴파일하면 없어진다.

- @Around("@annotation(annoationName)")


- AOP 적용 방법

- 컴파일 타임

- 로드 타임

- 런타임




** Web을 안띄우고 Springboot에서 테스트할 때는 아래와 같이 설정해준다.

- SpringApplication app = new SpringApplication(DemoSpringApplication.class);

- app.setWebApplicationType(WebApplication.NONE);

- app.run(args);

'#Spring' 카테고리의 다른 글

Dispatcher Servlet의 동작원리  (0) 2020.02.02
JPA Study  (0) 2019.05.19
Annotation을 이용한 Spring 설정  (0) 2019.01.06
Spring Bean Life Cycle  (0) 2019.01.06
DI (Dependency Injection)  (0) 2019.01.06