리루
Spring IoC / Bean 본문
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 |