본문 바로가기
CS/Web

스프링 프레임워크란? ( IoC, 스프링 mvc )

by 장장 2020. 8. 15.

프레임워크란? 

: 복잡한 문제를 해결하거나 서술하는 데 사용되는 기본 개념 구조

 

애플리케이션 프레임워크는 일관된 개발을 지원하고, 프레임워크에 정의된 경계에 따라 설정을 강제하고 재사용을 가능하게 하고 확장 가능하며 단순한 형태를 유지하면서 유지 관리성의 이익을 얻을 수 있는 장점이 있다.

 

[빈 + 컨테이너]

스프링 프레임워크 : 엔터프라이즈 애플리케이션을 개발하기에 적합한 프레임워크
                            객체 관리를 해주는 빈 컨테이너 프레임워크.

 

 


[ EJB와 POJO ]

- EJB (Enterprise Java Beans) 

: 애플리케이션에서 필요로 하는 비지니스 로직 뿐만 아니라, 많은 사용자의 처리 요구를 빠르고 안정적이게 유지하기 위해 필요한 로우레벨(트랜젝션, 상태 관리, 멀티쓰레딩, 보안 등) 처리로 인해 개발 시간이 많이 소요

이러한 문제를 해결하기 위해 나온 것이 EJB

 

=> EJB를 사용하면 애플리케이션 개발자는 로우 레벨의 기술들에 관심을 가질 필요도 없다!

 

하지만! 

EJB는 복잡한 프로그래밍 모델, 객체지향적이지 않음, 형편없는 개발생산성 등의 단점이 있다.

 

- POJO (plain old java object)

: 평범한 자바 오브젝트

 

EJB와 같이 잘못 설계된 과도한 기술을 피하고, 객체지향 원리에 따라 만들어진 자바 언어의 기본에 충실하게 비지니스 로직을 구현하는 방식으로 돌아가기 위해 나온 개념! 

 

마틴 파울러가 EJB와 같은 그럴듯한 이름이 없어서 사용을 주저하는 것이라고 결론을 내려 POJO라는 용어를 만들었다.

 

POJO를 사용하는 이유

  • 코드의 간결함 (비즈니스 로직과 특정 환경/low 레벨 종속적인 코드를 분리하므로 단순하다.)
  • 자동화 테스트에 유리 (환경 종속적인 코드는 자동화 테스트가 어렵지만, POJO는 테스트가 매우 유연하다.
  • 객체지향적 설계의 자유로운 사용

 

POJO 기반 프레임워크 

: POJO를 이용한 애플리케이션 개발이 가진 특징과 장점을 그대로 살리면서 EJB에서 제공하는 엔터프라이즈 서비스와 기술을 그대로 사용할 수 있도록 도와주는 프레임워크.

 

대표적 프레임워크 : 하이버네이트와 스프링.

 

 


 

[ IoC ]

: 제어의 역전 ( Inversion of Control )  

프로그램의 생명주기에 대한 주도권이 웹 애플리케이션에 있기 때문에 자바 웹 개발에서 특히 인기!

 

+) 의존 관계 역전의 원칙 (Dependency Inversion Principle) - 디자인 패턴 원칙

첫번째. 하이레벨 모듈은 로우레벨 모듈에 의존해서는 안 되고, 모두 인터페이스에 의존해야 한다.

두번째. 추상화는 세부사항에 의존해서는 안 된다.

=> 인터페이스를 활용함으로써 결합도를 낮추게 하자는 뜻.

 

자바에서는 인터페이스를 사용하더라도 결국 인스턴스화를 하려면 객체 생성에 필요한 코드가 수반! => 결합도 분리 X

이를 해결해주는 것이 바로 의존성 주입(DI : Dependency Injection)!

 

 

 

스프링에서 의존성을 주입할 때 기본적으로 타입을 기반으로 한다.

그리고, 자바에서 타입을 가장 잘 나타낼 수 있는 것은 인터페이스(interface)

 

 

+) 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Example {
    public static void main(String ar[]) {
        WorkService workService = new WorkService();
        WorkManager emp = new Employee();
        WorkManager boss = new Boss();
        
        workService.setWorkManager(emp);
        workService.askWork();
 
        workService.setWorkManager(boss );
        workService.askWork();
    }
}
cs

setter 메소드를 사용할 때 전달받는 클래스에 따라서 askWork의 내용이 달라짐.

 

 

스프링 컨테이너에 클래스를 등록하면 스프링이 클래스의 인스턴스를 관리!

스프링 컨테이너에 빈(bean)을 등록하고 설정하는 방법은 XML, Annotation

 

1. XML 사용

applicationContext.xml 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<bean id="boss" class="basic.boss"></bean>
<bean id="employee" class="basic.Employee"></bean>
 
<bean id="myWorkService" class="basic.WorkService">
    <property name="WorkManager">
        <ref bean="boss"/>
    </property>
</bean>
 
 
<bean id="yourWorkService" class="basic.WorkService">
    <property name="WorkManager">
        <ref bean="emp"/>
    </property>
</bean>
cs

 

bean의 클래스 속성에는 실제 클래스 파일 경로, id에는 참조할 사용 값

new 연산자를 사용해서 인스턴스를 생성했던 작업을 스프링에 위임!

 

 

GenericXmlApplicationContext 을 사용하여 xml 설정 이용

 

1
2
3
4
5
6
7
8
9
10
11
12
public class XmlSpringApp{
    public static void main(String[] args){
        GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml");
        WorkService yourWorkService = context.getBean("yourWorkService", WorkService.class);
        yourWorkService.askWork();
 
        WorkService workService = context.getBean("myWorkService", WorkService.class);
        workService.askWork();
 
        context.close();
    }
}
cs

 

 

xml 설정 시 빈 생명주기 제어

 

init-method : 스프링이 클래스에 의존성을 주입하면 자동으로 호출

destroy-method : 종료시 호출

<bean id="employee" class="basic.Employee" init-method="onCreated" destroy-method="onDestroyed"></bean>

 

 


 

2. 스프링 JavaConfig 설정 

xml를 사용하지 않고 자바 코드만으로 스프링 컨테이너 설정 가능 => 훨씬 간편

 

 

@Configuration을 이용한 설정

클래스 상단에 Configuration 어노테이션을 추가하여 빈 설정 정보가 포함된 클래스임을 명시!

<bean>태그는 @Bean 으로 대체

 

 

BeanConfig.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
public class BeanConfig{
    @Bean
    public WorkManager employee(){
        return new Employee();
    }
 
    @Bean
    public WorkManager boss(){
        return new Boss();
    }
 
    @Bean
    public WorkService yourWorkService(){
        WorkService workService = new WorkService();
        workService.setWorkManager(employee());
        return workService;
    }
 
    @Bean
    public WorkService myWorkService(){
        WorkService workService = new WorkService();
        workService.setWorkManager(boss());
        return workService;
    }
}
cs

 

BeanCofig 클래스의 설정을 이용해 실행하는 클래스

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class JavaConfigSpringApp{
    public static void main(String[] args){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(BeanConfig.class);
        context.refresh();
 
        WorkService yourWorkService = context.getBean("yourWorkService", WorkService.class);
        yourWorkService.askWork();
 
        WorkService myWorkService = context.getBean("myWorkService", WorkService.class);
        myWorkService.askWork();
 
        context.close();
    }
}
cs

 

AnnotationConfigApplicationCotext를 사용해서 @Bean 로드!

설정할 내용이 많을 경우는 설정 내용을 파일 별로 분리하고 @Import 를 사용해서 적용!

 

@Configuration
@Import(CompanyConfig.class)
public class BeanConfig {...}

 

어노테이션 설정 시 생명주기 제어

 

@PostConstruct, @PreDestroy 어노테이션을 사용

-> 별도의 설정과 클래스를 매핑하지 않고도 사용할 수 있다.

 

 


 

[ 스프링 MVC ]

 

 

DispatcherServlet : 가장 핵심적인 역할

요청을 받으면 그 요청을 처리할 수 있는 Handler의 이름을 HandlerMapping에게 물어본다.

 

HandlerMapping은 요청 URL을 보고 Handler를 판단, Handler 실행 전에 전처리, 훠리로 실행해야 할 인터셉터 목록 확인

 

DispatcherServlet은 제어권을 Handler로 전달.

 

Handler는 응답에 필요한 서비스 호출, 응답에서 렌더링해야하는 View Name 판단해서 DispatcherServlet에 전달.

 

DispatcherServlet는 논리적인 View Name을 ViewResolver에 전달해서 응답에 필요한 viw 생성

 

view에 model과 컨트롤러를 전달해서 응답 생성

 

응답 컨트롤러에 반환

 

 

DispatcherServlet 설정

 

컨트롤러 등록

1
2
3
4
<?xml version="1.0" emcpdomg="UTF-8"?>
<beans>
    <context:component-scan base-package="info.thecodinglive.controller" />
</beans>
cs

 

 

View Resolver 등록 -> prefix, suffix

1
2
3
4
5
6
7
<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass"
                value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>
cs

 

컨트롤러 예시

1
2
3
4
5
6
7
8
9
10
11
@Controller
public class IndexController{
    @RequestMapping("/")
    public ModelAndView home(){
        ModelAndView mv = new ModelAndView("home");
        mv.addObject("title""Jpub Spring WEB");
        mv.addObject("today"new Date().toString());
        System.out.println("index 컨트롤러");
        return mv;
    }
}
cs

 

 

 

댓글