-
KOSTA 교육 56일차(Spring, DI, AOP)Review 2020. 6. 24. 00:47
19. 1. 24(목)
배운 내용
- Spring이란 ?
- DI(Dependency Injection) 의존성 주입
- AOP
1. Spring이란?
엔터프라이즈 어플리케이션 개발을 편하게 해주는 프레임워크이다.
- 2003년에 등장하여 현재(2019)까지 사용되고 있다.
- 복잡성을 줄여주기 위한 목적을 가지고 있다.
- EJB사용을 하지 않기 위해 POJO(Plain Old Java Object)를 사용하여 가능하게 하였다.
- Maven을 사용하여 보다 편리하게 빌드 과정에서 라이브러리를 사용할 수 있다.
pom.xml에 dependencies 태그를 추가하여 라이브러리를 추가하면 자동으로 Maven이 생성된다.
- Maven 문제 발생 시 프로젝트에 빨간 느낌표가 발생한다.
해결 방안 : 툴 종료 → m2 폴더 → Repository 삭제 → 재실행
2. DI
IoC(Inversion of Control)이라고도 하며 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는게 아니라 주입 받아 사용하는 방법을 말함
- Service와 DAO가 높은 결합도로 되어 있다면 하나만 이상이 있어도 구동이 어렵다.
하지만 느슨한 결합을 통해 필요시 Container에서 객체를 꺼내와 구동이 쉽다.
Spring Container
- BeanFactory
- 애플리케이션 컴포넌트의 중앙 저장소
- 빈 설정 소스로부터 빈 정의를 읽어들이고, 빈을 구성하고 제공한다.
Bean
- Spring Container가 관리하는 객체
- 이름, 클래스, 스코프, 생성자, 프로퍼트(setter)를 가지고 있다.
Bean 객체 주입 방법 3가지
- Constructor 및 Property를 이용한 각각의 객체 주입
- Package를 이용한 객체 주입(annotation)
- Java 클래스를 사용(annotation)
Constructor 방식
- xml을 사용하여 객체들을 각각 주입하고 DI를 설정한다.
- <constructor-arg>를 사용하여 주입 받는다.
- ref = “bean id” → 객체를 주입시 사용
- value = “값” → 문자 주입시 사용
- Spring Bean Configuration File 생성한다.
- 위에 정의된 interface을 implements한 두개의 클래스를 출력하기 위하여 먼저 Bean 객체를 xml에 생성한다.
- bean 생성에서 id는 클래스 이름, class는 패키지를 포함한 경로를 선언한다.
- bean 출력에서는 id를 출력할 메인클래스 이름을(필자는 사용하기 편하게 service로 작성) class는 경로를 선언한다.
- bean을 불러 출력하기 위해 service 클래스에서 constructor-arg를 선언하고 객체를 받을 것이기 때문에 ref로 객체명을 선언한다.
- dao를 불러오기 위해 Dao 타입의 dao를 생성한다.
- dao를 넘겨주기 위해 생성자를 생성하고 insert 메소드에 dao의 메소드를 선언한다.
- 출력을 위한 메소드로서 Resource 함수를 통해 ClassPathResource를 생성하여 xml을 resources에 담는다.
- BeanFactory, GenericXMLApplicationContext를 통해 resources에 있는 bean을 factory에 집어넣는다.
- service 객체를 생성하고 factory.getBean(“service”)를 통해 factory에 있는 bean들을 가져온다.
- 가져온 Bean들을 service에서 Override한 메소드를 호출시킨다.
- 그렇다면 service에 있는 insert 메소드가 호출 된다.
- 여기서 dao.insertBoard() 메소드는 bean에서 OracleDao만 호출하였기 때문에 해당 객체만 호출된다.
- 만약 xml에서 객체를 mySQLdao로 주었다면
- MySQLDao가 호출 될 것이다.
Property 방식
- <Property>를 사용하여 주입 받는다.
- ref = “bean id” → 객체를 주입시 사용
- value = “값” → 문자 주입시 사용
- name = “객체에서 생성된 변수 명”
- dao는 객체에서 생성된 변수 명으로서 Service에서 가져온 객체이다.
- ref는 출력할 객체를 넣어준다.
- Property 태그에서 Dao를 가져온 변수인 dao가 있다.
- setter를 통해서 가져오기 때문에 set을 선언한 모습이다.
- 나머지는 Constructor와 동일한 조건이다.
- <context>를 사용하여 주입 받는다.
- 어노테이션을 지정해 주지 않았을 시 NoSuchBeanDefinitionException 오류가 발생한다.
- dependency한 라이브러리를 체크한다.
- context 태그를 사용하여 annotation-config를 선언한다.
- context : component-scan base-package= “패키지명”을 선언한다.
- 그리고 DI 설정을 한다. 하지만 constructor 혹은 property 처럼 따로 bean을 지정하지 않는다.
- 출력할 클래스를 Bean객체에 담기 위하여 Repository를 선언한다.
- Autowired는 dao를 넘겨줄 setter에 선언한다.
- Inject는 생성한 Dao 타입의 변수에 선언한다.(사용시 라이브러리 추가 필요)
- ApplicationContext를 사용하여 스프링 컨테이너를 생성한다.
- 생성한 컨테이너를 getBean(“id값”)을 통해 가져온다. (id값에는 항상 DI 설정의 id명과 동일해야 한다.)
- 오류가 뜨는 경우에는 Repository 어노테이션은 한 개의 객체만 취급 하기 때문에 중복되어 있는 경우를 생각해야한다.
Java 방식
- Container에 DAO를 가지고 있다가 Autowired 혹인 Inject로 객체를 가져다 준다
- Java 클래스에 Configuration 어노테이션 및 메소드에 Bean 어노테이션을 선언한다.
- 클래스명에 Configuration 어노테이션 선언
- 메소드에는 Bean 어노테이션 선언하여준다.
- 여기서 메소드명은 id명으로 선언한다.
- AnnotationConfigApplicationContext() Factory 클래스의 class를 호출한다.
3. AOP
기능을 핵심 로직과 공통 모듈로 구분하고 공통 모듈을 핵심 로직 사이사이에 끼워 넣는 개발 방법이다.
- 사용 용도 : 메소드 성능 검사, 트랜잭션 처리, 예외 반환 등
- 기존 OOP(객체)의 방법에서 공통된 모듈들을 적용하는데에는 각 객체별 중복된 코드가 생성되어야 한다. 때문에 AOP가 등장하였음
- 작업 순서 : 라이브러리 생성 → XML 생성 → 공통 모듈 클래스 생성 → 공통 모듈 메소드 생성
AOP 용어
- Aspect : 여러 객체에서 공통으로 적용되는 공통 관심사항
(ex:트랜 잭션, 로깅, 보안) - JoinPoint : Aspect가 적용 될 수 있는 지점(ex:메소드, 필드)
- Pointcut : 공통관심사항이 적용될 Joinpoint
→ pointcut에 의해 joinpoint가 결정된다. - Advice : 어느 시점(ex: 메소드 수행 전/후, 예외발생 후 등)에 어 떤 공통 관심기능(Aspect)을 적용할지 정의한 것.
- Weaving : 어떤 Advice를 어떤 Pointcut(핵심사항)에 적용시킬 것 인지에 대한 설정 (Advisor)
예시) 남자들 오늘 술먹자.
Aspect = 술먹자
joinpoint = 각각 남자
pointcut = 남자들
advice = 오늘AOP 사용 코드
<aop:config>
<aop:pointcut /> : pointcut 설정
<aop:aspect> : aspect를 설정
<aop:before /> : method 실행 전
<aop:after-returning /> : method 정상 실행 후
<aop:after-throwing /> : method 예외 발생 시
<aop:after /> : method 실행 후 (예외 발생 예부 상관 없음)
<aop:around /> : 모든 시점 적용 가능
</aop:aspect>
</aop:config>AOP 예제
- 라이브러리를 호출한다.
- 공통 모듈인 메소드 생성 후 try catch를 통해 핵심 로직을 호출한다.
- finally에서 로그 종료를 선언한다.
- logAspect id를 가진 Bean 객체를 생성한다.
- 라이브러리에서 추가한 부분을 NameSpace에서 체크 후 사용한다.
- 먼저 대상을 정해야 하기 때문에 pointcut 태그를 이용한다.
- expression에는 대상이 될 파일을 담는다. *은 전체 ..은 자식 .은 해당 클래스만 가능하다. id는 pointcut에 대한 id를 지정한다.
- aspect id는 클래스 이름을 ref는 생성한 bean의 id를 선언한다.
- around는 클래스에서 사용한 메소드를, ref는 pointcut의 메소드를 선언한다.
- 두개의 xml이 들어가기 때문에 배열로 선언하여준다.
- factory에 해당 배열을 담고 출력한다.
- Package를 부르는 context를 사용하여 서비스 객체를 생성하고 Repository를 이용하여 oracleDao를 출력하였다.
오늘 교육 간 느낀점
첫 Spring 수업을 들으면서 정말 편하면서도 이해하기 어렵다 생각했다.
일단 용어들이 지금까지 들었던 것과 많이 달라서 생소하여 어려웠고 Spring container 개념이 너무 어렵다. 객체를 컨테이너에 저장하고, 빼오는 과정이 xml과 java를 왔다갔다 명령어에 따라 판단하는게 쉽지 않은 것 같다.특히 어노테이션을 활용하여 객체로 만들 파일과 메소드 등을 정하는 방법이 생소하였고 익숙해지려면 시간이 좀 소요될 것 같다.
내일은 MVC 패턴을 배우게 되는데 벌써부터 진도가 빨라서 조금 부담되지만 프로젝트에 바로 적용하기 위해선 빨리 적응하는 것이 중요할 것 같다.'Review' 카테고리의 다른 글
KOSTA 교육 58일차(RequestParam, ModelAttribute, RESTful, PathVariable, tiles, File Up/Download, JSON, AOP, Transaction) (0) 2020.06.24 KOSTA 교육 57일차(Spring, MVC, myBatis, CRUD) (0) 2020.06.24 KOSTA 교육 55일차(Semi-Project 회고) (0) 2020.06.24 KOSTA 교육 54일차(Semi-Project, Ajax, jQuery, update) (0) 2020.06.24 KOSTA 교육 53일차(Semi-Project, Ajax, JavaScript, jQuery) (0) 2020.06.24