수업내용/Spring

[2022.12.29.목] 스프링 DI(의존성주입), AOP(관점지향), Maven

주니어주니 2022. 12. 29. 23:02

 

 

스프링

 

  • 오픈소스 프레임워크
    • 오픈소스 : 라이센스 무료, 가공/수익창출 허용
    • 프레임워크 : 특정한 아이디(개발방식, 개발패턴, 아키텍처)의 구현체
      - 라이브러리와 프레임워크
         * 라이브러리 : 개발에 필요한(자주 사용되는) 기능의 구현체
                                 필요한 기능이 구현되어 있는 라이브러리를 다운받아서 그 라이브러리의 기능을 사용한다.
         * 프레임워크 : 개발방식, 개발 패턴의 구현체 (ex. ibatis) 
                                 해당 프레임워크에서 제시하는 방식에 맞게 클래스나 인터페이스, 환경설정 정보를 구성하면
                                 프레임워크가 제공하는 기능을 제공받을 수 있다. 
  • Java 기반의 엔터프라이즈 애플리케이션 개발을 지원하는 프레임워크
  • DI(의존성 주입)의 구현체
    • 의존성 주입은 스프링의 가장 핵심적인 기능이다.
    • 인터페이스를 이용해 클래스와 클래스 간의 결합을 느슨하게 유지하고, 의존성 주입으로 의존하는 객체를 주입하면, 코드의 변경없이 의존하는 객체를 변경할 수 있다. 
    • 즉, 확장성이 매우 뛰어난 애플리케이션을 개발할 수 있다. 
  • AOP(관점지향 프로그래밍)의 구현체  
    • 관점지향 프로그램은 핵심 기능으로부터 프로그램의 공통관심사항을 분리시키는 것이다. 
    • 관점: 코드를 핵심관심사항(핵심기능)과 공통관심사항(공통기능)으로 구분하는 것이다.
    • 스프링의 AOP는 공통관심사항을 별도의 모듈(Advice와 Pointcut)로 개발하고, 공통관심사항이 적용될 대상과 시점을 지정하면 핵심기능이 구현된 메소드가 실행될 때마다 공통기능을 실행시킨다.
    • 즉, 메소드에서 공통관심사항 코드를 제거할 수 있다. (중복 제거
  • 스프링은 객체를 생성하는 공장이다.  ( Bean(객체) Factory. ) 
  • 스프링은 객체를 조립한다. (객체 간의 의존관계를 분석해서 필요로 하는 객체를 주입한다.) 

 

 


 

 

 

* 의존성 주입 (@Autowired)

 

 

 

 

 

UserDao 인터페이스를 구현한 UserOracleDao 구현클래스

UserController, OrderController는 인터페이스에 의존하고 있고, 이 안에서의 userDao가 가리키는 것은 UserOracleDao 안에 있는 UserDao를 가리킴 -> 재정의된 메소드 실행 

 

근데, 오라클 데이터베이스에서 마리아 데이터베이스로 변경이 생길 때 

마리아 데이터베이스도 UserDao 인터페이스를 구현

해당 인터페이스를 구현한 객체로 바꿔가면서 연결할 수 있음 

단, 다음의 조건을 충족해야 함 

1) Controller가 직접 객체를 만들면 안됨 (UserOracleDao, UserMariaDao같은 구체적인 클래스 이름이 등장하면 안돼)

2) 구체적인 구현클래스를 의존하지 않고, 인터페이스를 의존해야함 ( UserDao userDao; )

 

=> 코드를 하나도 건들지 않고 컨트롤러가 의존하는 객체를 변경할 수 있음 !!!

 

 

 

 

* 관점지향 프로그래밍 (@Aspect)

 

 

 

- 이렇게 하다보면, 핵심관심사항보다 공통관심사항을 호출하는 코드가 더 많아져버림 

-> 그래서 분리를 해야돼 

 

 

 

 

핵심관심사항을 남겨두고, 공통관심사항은 지워

공통관심을 밖으로 분리해서, 필요한 시점에 자동으로 외부에서 삽입되도록 하는 것 

Advice안에 Target을 지정해서 메소드 실행을 적용할 대상 지정

 

위에서는 공통관심사항을 일반 클래스에 넣음 -> 사용하려면 호출을 해야됨 

Advice 클래스 생성 - 공통관심사항을 구현 -> 얘가 공통기능을 실행 

이 공통기능이 적용되어야 하는 타겟을 정해서 스프링 환경설정 파일에 적어놔 

메소드를 호출하는 것이 아니라,

어떤 프로그램이 실행될 때마다 반드시 실행해야 하는 공통관심사항이 뭔지 Advice를 알려주는 것 

 

 

 

* Advice 작성 예 

 

-> @Aspect가 붙어있네? 그럼 스프링이 알아서 분석 

-> 대상 메소드가 실행되기 전에, service 패키지 안에 있는 모든 Service 클래스에 있는 모든 메소드를 실행할 때마다 공통관심사항 메소드가 적용 

 

 

-> 핵심기능이 구현된 코드에서 코드 변경없이 공통관심기능을 추가/삭제 -> 코드중복 제거, 핵심기능에 대한 유지보수, 재사용성 

 

 


 

 

스프링 컨테이너 

 

  • 애플리케이션에서 사용되는 객체의 라이프사이클(객체 생성, 조립, 유지/관리)을 관리한다.
  • 스프링 컨테이너의 종류
    • BeanFactory
      - spring-bean.jar에 포함되어 있는 스프링 컨테이너 인터페이스다.
      - 객체 생성, 객체 조립과 같은 간단한 기능만 제공하는 스프링 컨테이너다.  
      - 구현클래스 : xmlBeanFactory
    • ApplicationContext
      - spring-context.jar에 포함되어 있는 스프링 컨테이너 인터페이스다.
      - 객체 생성, 객체 조립, 관점지향 프로그래밍 지원, 국제화, EJB 연동 등 다양한 기능을 제공하는 스프링 컨테이너다.
      - 구현클래스 : ClasspathXmlApplicationContext, FilesystemXmlApplicationContext, GenericXmlApplicationContext, WebApplicationContext
    • webApplicationContext
      - spring-web.jar에 포함되어 있는 스프링 컨테이너 인터페이스다.
      - ApplicationContext 인터페이스와 기능은 유사하고, 웹 환경에 최적화되어 있는 스프링 컨테이너 인터페이스다.
      - 구현클래스 : XmlWebApplicationContext 

 

 


 

 

Maven

 

  • 자바의 프로젝트 빌드 도구 
  • 프로젝트의 라이브러리 의존성, 소스 컴파일, 패키징, 배포 등의 작업을 자동화할 수 있다. 
  • 프로젝트 생성/관리하는 도구
    • 메이븐 프로젝트는 pom.xml 파일을 포함하고 있다. 
      • pom.xml 파일은 프로젝트 정보를 표현하는 파일이다.
      • pom.xml 파일은 프로젝트의 최상위 폴더에 위치하고 있다.
      • pom.xml의 POM(Project Object Model : 메이븐에서 프로젝트를 표현하는 객체)을 설정하는 파일이다.
    • pom.xml의 주요 구성 요소
      • 프로젝트 정보
        <groupId />
           - 프로젝트를 생성하는 조직 또는 그룹명을 나타낸다.
           - 보통 URL의 역순으로 지정한다.
        <artifactId />
           - 프로젝트의 고유한 아이디다. (보통 프로젝트명)
           - 프로젝트 산출물의 고유한 아이디다.
        <version />
           - 애플리케이션의 버전을 나타낸다.
              (SNAPSHOT - 개발단계)
        <packaging />
           - 프로젝트 패키징 유형을 나타낸다.
           - jar, war, ear, pom 중 하나를 지정한다. 지정하지 않으면 jar
             (jar - 자바 프로젝트 패키징, war - 웹 애플리케이션 프로젝트를 톰캣에 배포하려면 war로 패키징)
        <name />
           - 프로젝트 명
        <description />
           - 프로젝트에 대한 설명
        <url />
           - 프로젝트를 찾을 수 있는 URL
        <properties />
           - pom.xml에서 중복해서 사용되는 설정값을 지정한다. 

      • 의존성 라이브러리 정보
        - 의존성 라이브러리를 정의하는 부분
        - 프로젝트에서 사용하는 라이브러리 정보를 정의한다.
        - 라이브러리정보는 groupId, artifactId, version 정보가 필요하다.

      • 빌드/배포 정보
        - 프로젝트의 빌드/배포와 관련된 설정정보를 정의하는 부분이다.

 

 

* spring-di/pom.xml 

 

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!-- 프로젝트 정보 -->
	<groupId>com.sample</groupId>
	<artifactId>spring-di</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<!-- pom.xml 파일에서 사용되는 프로퍼티값(상수값)을 설정한다. -->
	<properties>
		<!-- 프로젝트의 자바버전을 정의한다. -->
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
		<!-- 
			로그출력을 지원하는 slf4j 라이브러리의 버전 정보를 상수로 정의한다.
			<version>${slf4j.version}</version>와 같이 ${} 형식으로 값을 사용할 수 있다.
		 -->
		<slf4j.version>1.7.25</slf4j.version>
	</properties>

	<!-- 프로젝트의 의존성 라이브러리를 정의한다. -->
	<dependencies>
		<!-- 
			spring-context 라이브러리 의존성 정의
			spring-context 라이브러리 의존성은 spring-core, spring-beans, spring-aop, spring-expression 라이브러리도 포함한다.
			* 스프링을 이용해서 객체 생성, 의존성 주입, 관점지향 프로그래밍 실습이 가능하다.
		 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.3.24</version>
		</dependency>
		<!-- 
			로그 출력(내부적으로 어떤 일이 진행되는지 표시)을 지원하는 라이브러리 의존성 정의 
		 -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jul-to-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>log4j-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

	</dependencies>
</project>

 

 

* 스프링의 bean 설정파일 생성 (context-1.xml) 

 

 

* context-1.xml

 

 

조립된 모습

 

<bean> : 객체 생성
<property> : 객체 조립 

* 각 객체에 setter 메소드가 있어야 <property name=""> 에서 ctrl+space 했을 때 자동완성 됨

 

 

* UserController, OrderController