배운 내용
- 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를 출력하였다.
'KOSTA' 카테고리의 다른 글
KOSTA 교육 (RequestParam, ModelAttribute, RESTFul, PathVariable, tiles, File Up/Download, JSON, AOP, Transaction) (0) | 2021.04.23 |
---|---|
KOSTA 교육 (Spring MVC, mybatis, CRUD) (0) | 2021.04.22 |
KOSTA 교육 (Git, Software Develope Process, Semi-Project) (0) | 2021.04.22 |
소스트리(SourceTree) merge 시 주의사항! (0) | 2021.04.14 |
KOSTA 교육 (MVC, CRUD) (0) | 2021.04.07 |