본문 바로가기

KOSTA

KOSTA 교육 ( Spring, DI, AOP)

배운 내용

 

  1. Spring이란 ?
  2. DI(Dependency Injection) 의존성 주입
  3. 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가지 
  1. Constructor 및 Property를 이용한 각각의 객체 주입
  2. Package를 이용한 객체 주입(annotation)
  3. 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를 출력하였다.