ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 학원 day82. 스프링 의존성주입, 관점지향프로그래밍, Maven
    기록 2022. 12. 29. 12:55

    전자정부표준프레임워크에는 웹개발 지원하는 플로그인과 스프링을 지원하는 플로그인 등 다양한 플로그인이 깔려있어서 spring.io/tools에서 다운받지 않았다. (spring.io에서 다운받으면 jsp지원 안함.)

    --------------------------------------------------------------------------------------------------------------------------

    스프링

         - 오픈소스 프레임워크다.

            * 오픈소스 : 라이센스 무료, 가공/수익창출 허용

            * 프레임워크 : 특정한 아이디(개발방식, 개발 패턴, 아키텍처)의 구현체다. 

                     - 라이브러리와 프레임워크

                            * 라이브러리 : 개발에 필요한(자주 사용되는) 기능의 구현체다.

                                                    필요한 기능이 구현되어 있는 라이브러리를 다운받아서 그 라이브러리의 기능을 사용한다.

                            * 프레임워크 :  개발방식, 개발패턴의 구현체다. 

                                                     개발자는 해당 프레임워크에 제시하는 방식에 맞게 클래스나 인터페이스, 환경설정 정보를 구성하면 프레임워크가 제공하는 기능을 제공받을 수 있다. 

    - 라이브러리를 쓴다는 것은 내가 필요한 기능 중에 라이브러리에 있는 기능을 가져와서 쓴다는 것이고

    - 프레임워크를 쓴다는 것은 프레임워크에서 제시한 방법대로 개발하는 것이다. 프레임워크에 종속되는 것이다. 

    - Java 기반의 엔터프라이즈(서버에서 실행되는) 애플리케이션 개발을 지원하는 프레임워크다.

     

    - DI(의존성 주입)의 구현체다.

         * 의존성 주입은 스프링의 가장 핵심적인 개념이다.

         * 인터페이스를 이용해 클래스와 클래스 간의 결합을 느슨하게 유지하고, 의존성 주입으로 의존하는 객체를 주입한다면, 코드의 변경없이 의존하는 객체를 변경할 수 있다. 

         * 즉, 확장성이 매우 뛰어난 애플리케이션을 개발할 수 있다. 

     

    - AOP(관점지향 프로그래밍)의 구현체다.

         * 관점지향 프로그램은 프로그램의 공통관심사항을 핵심기능으로부터 분리시키는 것이다.

         * 관점은 코드를 핵심관심사항(핵심기능)과 공통관심사항(공통기능)으로 구분하는 것이다.

         * 스프링의 AOP는 공통관심사항을 별도의 모듈(Advice와 Pointcut)로 개발하고, 공통관심사항이 적용될 대상과 싯점을 지정하면 핵심기능이 구현된 메소드가 실행될 때마다 공통기능을 실행시킨다.

         * 즉, 메소드에서 공통관심사항 코드를 제거할 수 있다. (중복코드의 제거)

    - 스프링은 객체를 생성하는 공장이다. (Bean Factory다. Bean은 객체다.)

    - 스프링은 객체를 조립한다. (객체간의 의존관계를 분석해서 필요로 하는 객체를 주입한다.) 


    의존성 주입

         - 어떤 객체가 사용할 다른 객체를 획득하는 방식에 대한 이야기다. 

         - 필요한 객체를 직접 생성하는 것이 아니라, 제 3자로부터 제공받는 방식을 말한다. 

         - 스프링이 객체를 직접 생성하고, 객체들 간의 의존관계를 파악해서 필요한 객체를 제공하는 제 3자다.

    PostController

    // 새 게시글 등록 요청 처리

    // 페이지 번호에 해당하는 게시글 목록 요청 처리

    // 게시글번호에 해당하는 게시글 상세정보 요청 처리

    // 게시글 수정화면 요청처리

    // 게시글 수정 요청 처리

     

    PostDao

    void insertPost(Post post) {...}

    void updatePost(Post post) {...}

    List<Post> getPosts(Map param) {...}

    Post getPostByNo(int postNo) {...}

     

    PostDao가 있어야 DB엑세스가 가능하다.

     

    PostController는 PostDao를 사용한다.

    PostCotroller의 모든 기능들은 PostDao를 필요로 한다.

    PostController는 PostDao에 의존성을 가진다

     

    내가 필요한 객체가 무엇인지만 선언해놓으면, 제 3자(스프링)가 그 안에다가 필요한 객체를 넣어주는 것이다. 

    @Autowired 

    PostDao postDao; -> PostDao 필요해 라는 의미 (@Autowired라는 어노테이션을 붙여 놓는다.)

    클래스의 멤버변수로 선언해 놓는 것이다.

     

    1. PostController과 PostDao 객체를 생성한다.

    2. 생성한 객체들의 의존성을 조사한다.

          * PostController에 @Autowired PostDao postDao;가 발견됨

     

    @Autowired라는 어노테이션은

    PostController는 PostDao랑 같이 묶이고 싶다는 의사를 표현한 것이다.

     

    3. PostController 객체의 postDao 변수에 PostDao 객체를 대입한다.

      (PostController가 의존하는 객체를 스프링이 주입하였다.)

     

    의존성주입은 필요한 객체를 직접 생성하는 것이 아니라, 제 3자로부터 제공받는 방식이다. 

    스프링 = 의존성 주입의 구현체

    스프링은 직접 객체를 만들어서 객체들 간의 의존관계를 파악해서 필요한 객체를 제공해준다.

     

    클래스와 클래스가 의존하는 관계는 데이터베이스가 변경되거나 외부환경 등이 바뀌게 되면 Controller와 Dao를 모두 변경해야 하는 낭비가 있다. 

    프로그램의 확장성, 호환성이 떨어지고 있는 것이다. 

     

    반면에 스프링에서는..

    의존성주입

    UserDao라는 인터페이스를 만들 것이다. 

    구현체가 없는 메소드인 추상메소드가 정의되어 있다. 

    그리고 인터페이스를 구현한 구현클래스가 있다. 

     

    @Autowired라는 어노테이션은 UserDao가 필요하다고 알려준다.

    UserDao타입의 객체가 필요하다고 하는 것이다. (UserOracleDao를 적어놓지 않았다. UserDao 종류이기만 하면 된다고 적어 놓은 것임)

    UserDao는 인터페이스니까 객체를 못만든다.

    스프링한테 UserDao를 구현한 클래스로 객체를, UserController, OrderController 객체를 만들라고 시킨다. (환경설정정보에 적어 놓는다.)

    그래서 스프링이 의존성을 조사하는데 UserDao타입의 객체를 찾고, 주입되는 것이다.

     

    의존성주입이라는 효과가 발휘되기 위해서는 인터페이스가 필요하다. 

    인터페이스는 표준을 정의할 때 쓴다. 사용방법을 통일시키려고 만든다.

    사용자 정보를 넣을 때는 무조건 inserUser, 사용자 정보를 조회할 때는 무조건 getUserById였으면 좋겠다는 것이다.

     

    UserOracleDao 내부에 UserDao인터페이스가 존재한다. 

    스프링이 필요한 객체를 생성하고, 생성한 객체에서 의존 관계를 분석한다. 

    Autowired가 붙어있는 UserDao타입을 구현한 객체가 필요하다고 하는 것이다. 

    부모타입의 객체는 자식타입의 객체를 참조할 수 있다. 

    재정의된 것이 실행되면 오라클 데이터베이스와 연결된다.

     

    UserOracleDao이든 UserMariaDao이든 모두 UserDao라는 인터페이스를 구현하였다. 

    스프링이 의존성 정보를 분석한다. 

    어노테이션을 확인하여 UserDao타입의 객체가 필요하다는 것을 확인함. 

    userDao변수에 UserDao타입의 객체를 주입한다.

     

    UserController 코드를 하나도 안바꾸고 UserController가 사용할 객체를 변경할 수 있는 것이다. 

    그렇게 하기 위해서 인터페이스가 필요한 것이다. 

    인터페이스를 의존하게 만들면 구현객체를 교체할 수 있는 것이다. 

    1. UserController가 직접 객체를 만들면 안된다. (제3자로부터 제공받는다.)

    2. 클래스가 구체적인 구현클래스를 의존하게 하면 안된다. 인터페이스를 의존하게 해야 한다.

    (클래스가 클래스를 의존하는 건 '강한 결합'이라고 부르고, 클래스가 인터페이스를 의존하는 건 '느슨한 결합'이라고 부름)

    (실제로 사용할 객체(인터페이스를 구현한 클래스)는 의존성주입을 통해 제공해준다.)

     

    따라서, 스프링을 사용하면 확장성, 호환성이 뛰어나다.


    AOP(관점지향 프로그래밍)의 구현체

    * 관점지향 프로그램은 프로그램의 공통관심사항을 핵심기능으로부터 분리시키는 것이다.

    * 관점은 코드를 바라보는 시각이다. (메소드 안에 무슨 코드가 있지?)

     

    공통 관심사항 : 모든 메소드 안에 공통적으로 들어있는 코드  (예시 : 로그출력)

    핵심 관심사항 : 각 메소드별로 개별적으로 들어있는 코드

     

    관점지향 프로그래밍을 사용하면 공통관심사항 코드를 지워버려도 실행시킬 수 있게 한다.

    메소드에 작성되어 있는 코드를 2가지로 나눠서 바라본다. 핵심관심사항인지 공통관심사항인지를 구별한다.

    공통관심사항이 많아질 수 있다. 

    공통관심사항 메소드를 실행시키려면 호출하는 코드를 없앨 수는 없는데 관점지향 프로그래밍에서는 

    공통관심사항 메소드를 호출하는 코드를 삭제하여 핵심관심사항 코드만 남긴다.

    Advice라는 공통관심사항이 구현되어 있는 클래스를 만든다. 

     

    스프링 환경설정 파일에 학생등록기능 메소드를 실행할 때 loggingAdvice를 실행하라고 적어놓는다.

    공통기능 적용이 되는 타겟을 적어놓는다.

     

    Advice 프로그램의 작성예

    @Before("within(com.sample.service.*Service)")   <- com.sample.service패키지의 모든 Service로 끝나는 클래스의 메소드가 실행되기 전에 공통관심사항을 실행되게 할 거라는 의미다.

       

    @Aspect가 적혀있으면 스프링이 분석한다. 

     

    스프링의 관점지향 프로그래밍

    - AOP관련 @어노테이션을 이용해서 설정한다.

         - @Aspect : 관점지향 프로그래밍 관련 객체임을 나타내는 어노테이션이다.

         - @Before : 공통관심사항을 실행할 싯점을 나타내는 어노테이션이다.

                @Before, @After, @AfterReturning, @AfterThrowing, @Around

         - "within(com.sample.service.*Service)" : 포인트컷(Pointcut Expression)이다. 

             포인트컷은 공통관심사항 적용대상을 나타내는 표현식이다.

             예제의 표현식은 패키지명이 com.sample.service이고, 

                                        클래스명이 Service로 끝나는 모든 클래스의 메소드가 적용대상이다. 

     

    * 핵심기능이 구현된 메소드에서 공통관심사항 코드를 제거할 수 있다. 

       (코드의 중복이 제거된다.)

    * 핵심기능이 구현된 메소드의 코드 변경없이 공통관심사항을 추가/삭제할 수 있다. 

    * 핵심기능에 대한 유지보수가 쉬워진다. 

    * 핵심기능의 재사용성도 높아진다.


    Maven

    - 자바의 프로젝트 빌드 도구다.

    - 프로젝트의 라이브러리 의존성, 소스 컴파일, 패키징, 배포 등의 작업을 자동화할 수 있다. (war, jar를 통해)

    - 프로젝트 생성/관리하는 도구다.

         * 메이븐 프로젝트는 pom.xml 파일을 포함하고 있다.

              - pom.xml파일은 프로젝트 정보를 표현하는 파일이다. 

              - pom.xml파일은 프로젝트의 최상위 폴더에 위치하고 있다.

              - pom.xml의 POM(Project Object Model)을 설정하는 파일이다. 

              - POM은 메이븐에서 프로젝트를 표현하는 객체다. (브라우저에서 html을 표현하는 객체가 DOM이었듯이)

     

         * pom.xml의 주요 구성 요소

               - 프로젝트 정보 

                    <groupId /> 

                               프로젝트를 생성하는 조직 또는 그룹명을 나타낸다. 

                               보통 URL의 역순으로 지정한다.

                    <artifactId />

                               프로젝트의 고유한 아이디 (보통은 프로젝트명과 같은 이름)

                               프로젝트 산출물의 고유한 아이디다.

                    <version />

                               애플리케이션의 버전을 나타낸다. (release - 제품화됨, snapshot - 개발단계에 있다는 것을 의미함)

                    <packaging />

                               프로젝트 패키징 유형을 나타낸다.

                               jar, war, ear, pom 중 하나를 지정한다. 지정하지 않으면 jar다.  jar는 웹어플리케이션 자바프로젝트를 패키징하면 jar가 되고, 웹어플리케이션 프로젝트를 톰캣에 배포하려면 war라는 형태로 패키징해야한다. ear는 요즘 안쓴다. pom은 프로젝트는 아니고, 프로젝트에 관련된 정보들만 있는 프로젝트이다. 실제 소스코드는 없다. 프로젝트에서 사용하는 라이브러리들을 모아둔 부모프로젝트라고 볼 수 있다.

                     <name />

                               프로젝트명이다.

                     <description />

                                프로젝트에 대한 설명이다.

                     <url />

                                프로젝트를 찾을 수 있는 URL이다.

                     <properties />

                                 pom.xml에서 중복해서 사용되는 설정값을 지정한다.

     

               - 의존성 라이브러리 정보

                      의존성 라이브러리를 정의하는 부분이다. 

                      프로젝트에서 사용하는 라이브러리 정보를 정의한다.

                      라이브러리정보는 groupId, artifactId, version 정보가 필요하다.

         메이븐은 pom.xml에 있는 라이브러리 정보를 보고 라이브러리를 maven.repository에서 다운로드 받는다. 

        위의 폴더에서 다운받은 라이브러리를 확인할 수 있다. 

    * 스프링부트에서는 New Spring Starter Project에서 검색해서 만들어줄 수 있다.

     

     - 빌드/배포 정보 

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


    logback.xml은 pom.xml에서 로그출력을 지원하는 라이브러리 의존성 정의한 곳에 적어놓은 라이브러리의 설정파일이다.

    logback.xml에 정의된대로 로그가 출력된다.

     

    src/main/resources의 spring폴더에서 Spring Bean Configuration File 을 클릭하고 context-1.xml을 만든다.

    스프링의 빈 설정파일인데, 내가 만들고 싶은 객체를 적어놓으면 스프링이 객체를 만들어준다.

     

    스프링 컨테이너

       - 애플리케이션에서 사용되는 객체의 라이프사이클(객체 생성, 조립, 유지관리)을 관리한다. (톰캣은 서블릿/jsp의 라이프사이클을 관리하는 것과 같음.)

       - 스프링 컨테이너의 종류

           BeanFactory

                  spring-bean.jar에 포함되어 있는 스프링 컨테이너 인터페이스다. 

                  객체 생성, 객체조립과 같은 간단한 기능만 제공하는 스프링 컨테이너다.

                  구현클래스 : XmlBeanFactory

           ApplicationContext

                 spring-context.jar에 포함되어 있는 스프링 컨테이너 인터페이스다.

                객체 생성, 객체 조립, 관점지향 프로그래밍 지원, 국제화, EJB 연동 등 다양한 기능을 제공하는 스프링 컨테이너다.

                 구현클래스 : ClasspathXmlApplicationContext, FilesystemApplicationContext, GenericXmlApplicationContext, 

           WebApplicationContext 

                 spring-web.jar에 포함되어 있는 스프링 컨테이너 인터페이스다.

                 ApplicationContext 인터페이스와 기능은 유사하고, 웹 환경에 최적화되어 있는 스프링 컨테이너 인터페이스다. 

                 구현클래스 : XmlWebApplicationContext

     

    App1.java
    App1.java 출력결과

    App1.java를 출력하면 logback.xml에 적혀있는 로그정보와 싱글턴 객체인 UserController, UserOracleDao를 만들었다고 알려주고 있다.

     

    context-1.xml

    userOracleDao라는 멤버변수 property에 userDao라는 식별자로 찾아지는 객체를 참조하라는 의미이다.

    Bean은 객체 생성시키는 태그

    property는 객체 조립시키는 태그

    id는 중복되지 않는 선에서 내맘대로 지을 수 있다.

     

    스프링은 모든 객체를 싱글턴으로 만든다. 객체를 하나만 만든다. 

     

    댓글

Designed by Tistory.