반응형

 

 

 

 

 

Spring JDBC

  • JDBC 프로그래밍을 보면 반복되는 개발 요소가 있습니다.
  • 이러한 반복적인 요소는 개발자를 지루하게 만듭니다.
  • 개발하기 지루한 JDBC의 모든 저수준 세부사항을 스프링 프레임워크가 처리해줍니다.
  • 개발자는 필요한 부분만 개발하면 됩니다.

 

Spring JDBC - 개발자가 해야 할 일은?

spring JDBC

 

 

Spring JDBC 패키지

org.springframework.jdbc.core

  • JdbcTemplate 및 관련 Helper 객체 제공

org.springframework.jdbc.datasource

  • DataSource를 쉽게 접근하기 위한 유틸 클래스, 트랜젝션매니져 및 다양한 DataSource 구현을 제공

org.springframework.jdbc.object

  • RDBMS 조회, 갱신, 저장등을 안전하고 재사용 가능한 객제 제공

org.springframework.jdbc.support

  • jdbc.core 및 jdbc.object를 사용하는 JDBC 프레임워크를 지원

 

JDBC Template

  • org.springframework.jdbc.core에서 가장 중요한 클래스입니다.
  • 리소스 생성, 해지를 처리해서 연결을 닫는 것을 잊어 발생하는 문제 등을 피할 수 있도록 합니다.
  • 스테이먼트(Statement)의 생성과 실행을 처리합니다.
  • SQL 조회, 업데이트, 저장 프로시저 호출, ResultSet 반복호출 등을 실행합니다.
  • JDBC 예외가 발생할 경우 org.springframework.dao패키지에 정의되어 있는 일반적인 예외로 변환시킵니다.

 

 


실습코드

JdbcTemplate select 예제1

열의 수 구하기

int rowCount = this.jdbcTemplate.queryForInt("select count(*) from t_actor");

 

JdbcTemplate select 예제2

변수 바인딩 사용하기

int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt("select count(*) from t_actor where first_name = ?", "Joe");

 

JdbcTemplate select 예제3

String값으로 결과 받기

String lastName = this.jdbcTemplate.queryForObject("select last_name from t_actor where id = ?", new Object[]{1212L}, String.class);

 

JdbcTemplate select 예제4

한 건 조회하기

Actor actor = this.jdbcTemplate.queryForObject(

  "select first_name, last_name from t_actor where id = ?",

  new Object[]{1212L},

  new RowMapper<Actor>() {

    public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {

      Actor actor = new Actor();

      actor.setFirstName(rs.getString("first_name"));

      actor.setLastName(rs.getString("last_name"));

      return actor;

    }

  });

 

JdbcTemplate select 예제5

여러 건 조회하기

List<Actor> actors = this.jdbcTemplate.query(

  "select first_name, last_name from t_actor",

  new RowMapper<Actor>() {

    public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {

      Actor actor = new Actor();

      actor.setFirstName(rs.getString("first_name"));

      actor.setLastName(rs.getString("last_name"));

      return actor;

    }

  });

 

 

JdbcTemplate select 예제6

중복 코드 제거 (1건 구하기와 여러 건 구하기가 같은 코드에 있을 경우)

public List<Actor> findAllActors() {

  return this.jdbcTemplate.query( "select first_name, last_name from t_actor", new ActorMapper());

}

private static final class ActorMapper implements RowMapper<Actor> {

  public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {

    Actor actor = new Actor();

    actor.setFirstName(rs.getString("first_name"));

    actor.setLastName(rs.getString("last_name"));

    return actor;

  }

}

 

 

JdbcTemplate insert 예제

INSERT 하기

this.jdbcTemplate.update("insert into t_actor (first_name, last_name) values (?, ?)",  "Leonor", "Watling");

 

JdbcTemplate update 예제

UPDATE 하기

this.jdbcTemplate.update("update t_actor set = ? where id = ?", "Banjo", 5276L);

 

JdbcTemplate delete 예제

DELETE 하기

this.jdbcTemplate.update("delete from actor where id = ?", Long.valueOf(actorId));

 

 

JdbcTemplate외의 접근방법

NamedParameterJdbcTemplate

SimpleJdbcTemplate

  • JdbcTemplate과 NamedParameterJdbcTemplate 합쳐 놓은 템플릿 클래스
  • 이제 JdbcTemplate과 NamedParameterJdbcTemplate에 모든 기능을 제공하기 때문에 삭제 예정될 예정(deprecated)
  • SimpleJdbcTemplate 예제

SimpleJdbcInsert

 

 


생각해보기

  1. JDBC 프로그래밍이 불편해서 이를 해결하기 위해서 등장한 기술에는 Spring JDBC 외에도 다양한 기술들이 존재합니다. 대표적으로 JPA와 MyBatis가 그러한 기술입니다. 문제를 해결하는 방법이 왜 여러 가지가 존재할끼요?
  2.  

http://blog.naver.com/PostView.nhn?blogId=admass&logNo=220870636605

 

한 DB에 Spring JPA와 Mybatis를 동시에 활용하기

Spring JPA와 Mybatis는 각각 장단점이 있습니다. Spring JPA의 경우에는 객체 단위로 CUD가 ...

blog.naver.com

Spring JPA와 Mybatis는 각각 장단점이 있습니다.

Spring JPA의 경우에는 객체 단위로 CRUD가 가능합니다. 일반적으로 CUD는 단일 테이블에 대하여 작업을 하는 경우가 많은데 Mybatis에서 하게 되면 해당 쿼리를 직접 짜고, 들어오는 Parameter에 대하여 모두 확인하여 처리해야 하는 경우가 많습니다.

그러나 MyBatis의 장점을 무시할 순 없습니다. ER-DB를 사용하는 경우 자기가 원하는 Query를 짜서 직접 데이터를 손쉽게 전달하고 처리할 수 있다는 장점이 있죠. 특히, Spring JPA에서 활용하는 상당히 복잡한 나름대로의 SQL을 배워야 하고, 테이블 Join을 하게 될 경우 해당 조건을 객체구조에도 녹여내야 하는 등 배우고 익혀서 적용해야 할 포인트가 많아지게 됩니다.

 

 

 

 

반응형
반응형

 

 

 

Java config를 이용한 설정을 위한 어노테이션

@Configuration

  • 스프링 설정 클래스를 선언하는 어노테이션

@Bean

  • bean을 정의하는 어노테이션

@ComponentScan

  • @Controller, @Service, @Repository, @Component 어노테이션이 붙은 클래스를 찾아 컨테이너에 등록

@Component

  • 컴포넌트 스캔의 대상이 되는 애노테이션 중 하나로써 주로 유틸, 기타 지원 클래스에 붙이는 어노테이션

@Autowired

  • 주입 대상이되는 bean을 컨테이너에 찾아 주입하는 어노테이션

 

 

 

Java Config를 이용해 설정하기

ApplicationConfig.java

package kr.or.connect.diexam01;
import org.springframework.context.annotation.*;

@Configuration
public class ApplicationConfig {
	@Bean
	public Car car(Engine e) {
		Car c = new Car();
		c.setEngine(e);
		return c;
	}
	
	@Bean
	public Engine engine() {
		return new Engine();
	}
}

 

@Configuration 은 스프링 설정 클래스라는 의미를 가집니다.

JavaConfig로 설정을 할 클래스 위에는 @Configuration가 붙어 있어야 합니다.

ApplicationContext중에서 AnnotationConfigApplicationContext는 JavaConfig클래스를 읽어들여 IoC와 DI를 적용하게 됩니다.

이때 설정파일 중에 @Bean이 붙어 있는 메소드들을 AnnotationConfigApplicationContext는 자동으로 실행하여 그 결과로 리턴하는 객체들을 기본적으로 싱글턴으로 관리를 하게 됩니다.

 

ApplicationContextExam03.java

package kr.or.connect.diexam01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextExam03 {

	public static void main(String[] args) {
		ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		   
		Car car = (Car)ac.getBean("car");
		car.run();
		
	}
}

파라미터로 요청하는 class 타입으로 지정 가능합니다.

Car car = ac.getBean(Car.class);

 

ApplicationConfig2.java

package kr.or.connect.diexam01;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan("kr.or.connect.diexam01")
public class ApplicationConfig2 {
}

 

기존 JavaConfig에서 빈을 생성하는 메소드를 모두 제거했습니다.

단, @Configuration아래에 @ComponentScan이라는 어노테이션을 추가했습니다.

@ComponentScan어노테이션은 파라미터로 들어온 패키지 이하에서 @Controller, @Service, @Repository, @Component 어노테이션이 붙어 있는 클래스를 찾아 메모리에 몽땅 올려줍니다.

기존의 Car클래스와 Engine클래스 위에 @Component를 붙이도록 하겠습니다.

 

Engine.java

package kr.or.connect.diexam01;

import org.springframework.stereotype.Component;

@Component
public class Engine {
	public Engine() {
		System.out.println("Engine 생성자");
	}
	
	public void exec() {
		System.out.println("엔진이 동작합니다.");
	}
}

 

Car.java

package kr.or.connect.diexam01;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Car {
	@Autowired
	private Engine v8;
	
	public Car() {
		System.out.println("Car 생성자");
	}
	
	public void run() {
		System.out.println("엔진을 이용하여 달립니다.");
		v8.exec();
	}
}

수정된 JavaConfig를 읽어들이여 실행하는 클래스를 보도록 하겠습니다.

 

ApplicationContextExam04.java

package kr.or.connect.diexam01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextExam04 {

	public static void main(String[] args) {
		ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig2.class);
		   
		Car car = ac.getBean(Car.class);
		car.run();
		
	}
}

Spring에서 사용하기에 알맞게 @Controller, @Service, @Repository, @Component 어노테이션이 붙어 있는 객체들은 ComponentScan을 이용해서 읽어들여 메모리에 올리고 DI를 주입하도록 하고, 이러한 어노테이션이 붙어 있지 않은 객체는 @Bean어노테이션을 이용하여 직접 생성해주는 방식으로 클래스들을 관리하면 편리합니다.

 

 


생각해보기

  • 다루는 빈(Bean)이 많아질수록 xml로 설정하는 것과 @ComponentScan, @Component, @Autowired를 이용하는 것 중 어떤 것이 유지보수에 좋을 것 같습니까?
  • @AutoWired 는 Field, Constructor, Setter Method 에 사용할 수 있습니다. 각각의 방식에 장단점에 대해서 더 생각해보세요.

 

1. 후자의 경우가 좀 더 유지보수하기에 좋을 것같습니다. xml로 설정하게될경우 우선순위는 좀 더 높지만 일일이 id를 지정해줘야하고 그에맞게 연결해줘야하는데 이건 여간 힘든작업이란 생각이 듭니다.

2. 아직은 좀 더 와닿지는않지만 아래의 URL에 설명이 잘되어있더군요.

https://yaboong.github.io/spring/2019/08/29/why-field-injection-is-bad/

반응형
반응형

 

 

 

 

DI 확인하기

이번에는 DI 즉 의존성 주입을 확인해보도록 하겠습니다.

Car와 Engine이라는 클래스 2개를 생성합니다.

 

 


실습코드

Engine.java

package kr.or.connect.diexam01;

public class Engine {
	public Engine() {
		System.out.println("Engine 생성자");
	}
	
	public void exec() {
		System.out.println("엔진이 동작합니다.");
	}
}

 

Car.java

package kr.or.connect.diexam01;

public class Car {
	Engine v8;
	
	public Car() {
		System.out.println("Car 생성자");
	}
	
	public void setEngine(Engine e) {
		this.v8 = e;
	}
	
	public void run() {
		System.out.println("엔진을 이용하여 달립니다.");
		v8.exec();
	}
}

 

위의 Car 클래스가 제대로 동작하도록 하려면 보통 다음과 같은 코드가 작성되야 합니다.

Engine e = new Engine();
Car c = new Car();
c.setEngine( e );
c.run();

 

1, 2 번째 줄을 Spring 컨테이너에게 맡기기 위해 설정파일에 다음과 같은 코드를 입력합니다.

<bean id="e" class="kr.or.connect.diexam01.Engine"></bean>
<bean id="car" class="kr.or.connect.diexam01.Car">
	<property name="engine" ref="e"></property>
</bean>

 

즉, 위의 XML설정은 다음과 같은 의미를 가집니다.

Engine e = new Engine();
Car c = new Car();
c.setEngine( e );

이번엔 위의 설정 파일을 읽어들여 실행하는 ApplicationContextExam02.java를 작성해보도록 하겠습니다.

package kr.or.connect.diexam01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ApplicationContextExam02 {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext( 
				"applicationContext.xml"); 

		Car car = (Car)ac.getBean("car");
		car.run();
		
	}
}

콘솔을 보면 다음과 같이 실행된 것을 알 수 있습니다.

 

 

생각해보기

  • Spring컨테이너가 관리하는 객체를 빈(Bean)이라고 말합니다. (여러분들이 직접 new연산자로 생성해서 사용하는 객체는 빈(Bean)이라고 말하지 않습니다.) Spring은 빈을 생성할 때 기본적으로 싱글톤(Singleton)객체로 생성합니다. 싱글톤이란 메모리에 하나만 생성한다는 것입니다. 메모리에 하나만 생성되었을 경우, 해당 객체를 동시에 이용한다면 어떤 문제가 발생할 수 있을까요? 이런 문제를 해결하려면 어떻게 해야할까요?   ( 참고로 Spring에서 빈을 생성할 때 스코프(scope)를 줄 수 있습니다. 스코프를 줌으로써 기본으로 설정된 싱글톤 외에도 다른 방법으로 객체를 생성할 수 있습니다. )

 

운영체제나 데이터베이스에서 나타나는 동기/비동기와 관련된 문제가 생길 수 있다고 생각합니다. 같은 객체에 동시에 다른 사용자가 접근하여 몇 명은 수정을, 몇 명은 참조를 진행한다면 문제가 생길 수 있습니다. 또한 이를 막기 위해 코딩을 하다보면 데드락과 관련된 이슈도 나올 수 있다고 생각합니다.

반응형
반응형

 

 

 

 

 

Maven으로 Java프로젝트 만들기

 

 

 

 

pom.xml 파일에 JDK를 사용하기 위한 플러그인 설정을 추가합니다.

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>kr.or.connect</groupId>
  <artifactId>diexam01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>diexam01</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
-------------------------------------추가----------------------------------------------------
  <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
  </build>
----------------------------------------------------------------------------------------------

</project>

 

: 전 이미 maven-compiler-plugin 이 이미 있기 때문에 버전만 1.7에서 1.8로 변경하였습니다.

 

 

프로젝트를 선택하고, Maven -> Update Project를 선택합니다.

위와 같은 창이 뜨면 OK버튼을 클릭합니다.

 

 


실습코드

App.java

package kr.or.connect.diexam01;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

 

AppTest.java

package kr.or.connect.diexam01;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest 
    extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp()
    {
        assertTrue( true );
    }
}

 

 

AppTest.java 를 선택한 후 우측버튼을 클릭하고 Run As -> JUnit Test 메뉴를 선택합니다.

하단의 JUnit 뷰에 하나의 테스트가 성공했다는 메시지와 함께 녹색 막대가 보여집니다.

Bean class란?

예전에는 Visual 한 컴포넌트를 Bean이라고 불렀지만, 근래 들어서는 일반적인 Java클래스를 Bean클래스라고 보통 말합니다.

Bean클래스의 3가지 특징은 다음과 같습니다.

  • 기본생성자를 가지고 있습니다.
  • 필드는 private하게 선언합니다.
  • getter, setter 메소드를 가집니다.
  • getName() setName() 메소드를 name 프로퍼티(property)라고 합니다. (용어 중요)

 

 


실습코드

UserBean.java

package kr.or.connect.diexam01;

//빈클래스
public class UserBean {
	
	//필드는 private한다.
	private String name;
	private int age;
	private boolean male;
	
	//기본생성자를 반드시 가지고 있어야 한다.
	public UserBean() {
	}
	
	public UserBean(String name, int age, boolean male) {
		this.name = name;
		this.age = age;
		this.male = male;
	}

	// setter, getter메소드는 프로퍼티라고 한다.
	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public boolean isMale() {
		return male;
	}

	public void setMale(boolean male) {
		this.male = male;
	}

}

 

Spring Bean Factory를 이용하여 Bean객체 이용하기

1) 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>kr.or.connect</groupId>
  <artifactId>diexam01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>diexam01</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version> 4.3.14.RELEASE</spring.version>
  </properties>

  <dependencies>
	<!-- Spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
  
  
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
  <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
  </build>
</project>

 

2) 추가된 라이브러리 확인합니다.

 

3) resources 소스 폴더를 생성합니다.

프로젝트를 선택하고, 오른쪽 버튼을 클릭한 후 New -> Folder를 선택합니다.

src/main 폴더를 선택한 후 forder name에 resources라고 Finish버튼을 클릭합니다.

 

해당 폴더를 선택하고, 우측버튼을 클릭하여 New – File을 선택합니다. src/main/resources 폴더를 선택한 후 File name에 applicationContext.xml 을 입력하고 Finish버튼을 클릭합니다.

위와 같이 생성되었으면 더블클릭하여 파일을 엽니다.

4) resources 소스 폴더에 xml 파일을 작성합니다.

 

 


실습코드 

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="userBean" class="kr.or.connect.diexam01.UserBean"></bean>

</beans>

bean 태그를 하나 입력했는데, 위의 태그는 다음과 같은 의미를 가집니다.

UserBean userBean - new UserBean();

 

ApplicationContext를 이용해서 설정파일을 읽어들여 실행하기

ApplicationContextExam01

package kr.or.connect.diexam01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ApplicationContextExam01 {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext( 
				"classpath:applicationContext.xml"); 
		System.out.println("초기화 완료.");
		
		UserBean userBean = (UserBean)ac.getBean("userBean");
		userBean.setName("kim");
		System.out.println(userBean.getName());
		
		UserBean userBean2 = (UserBean)ac.getBean("userBean");
		if(userBean == userBean2) {
			System.out.println("같은 인스턴스이다.");
		}
		
	}
}
반응형
반응형

 

 

 

1. 부분 자르기

string str;

str.substr(4);
str.substr(0, 10);

 

str.substr(n) : n번째 인덱스부터 끝까지 반환

str.substr(n, m) : n번째 인덱스부터 m개의 문자를 반환

 

 

 

2. printf로 출력하기

string str;

printf("%s\n", str.c_str());

printf로 출력하고 싶다면 .c_str()를 붙여주어야 한다.

 

 

 

3. 인덱스 사용하기

string str;

str[0];
str[4];

str[0] : 인덱스 0번째 문자를 반환한다.

str[4] : 인덱스 4번째 문자를 반환한다.

 

 

 

4. 공백을 포함하여 엔터가 나올때까지 입력받기

string str;

getline(cin, str);

getline(cin, str) 하면 엔터 나올때까지 공백을 포함하여 입력받을 수 있다.

 

 

5. 문자열 길이

str.length();

 

반응형
반응형

 

 

 

컨테이너(Container)

컨테이너는 인스턴스의 생명주기를 관리하며, 생성된 인스턴스에게 추가적인 기능을 제공합니다.

예를 들어, Servlet을 실행해주는 WAS는 Servlet 컨테이너를 가지고 있다고 말합니다.

WAS는 웹 브라우저로부터 서블릿 URL에 해당하는 요청을 받으면, 서블릿을 메모리에 올린 후 실행합니다.

개발자가 서블릿 클래스를 작성했지만, 실제로 메모리에 올리고 실행하는 것은 WAS가 가지고 있는 Servlet 컨테이너입니다.

Servlet컨테이너는 동일한 서블릿에 해당하는 요청을 받으면, 또 메모리에 올리지 않고 기존에 메모리에 올라간 서블릿을 실행하여 그 결과를 웹 브라우저에게 전달합니다.

컨테이너는 보통 인스턴스의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 제공하는 것을 말합니다.

 

IoC(Inversion of Control) 

컨테이너가 코드 대신 오브젝트의 제어권을 갖고 있어 IoC(제어의 역전)이라 합니다.

예를 들어, 서블릿 클래스는 개발자가 만들지만, 그 서블릿의 메소드를 알맞게 호출하는 것은 WAS입니다.

이렇게 개발자가 만든 어떤 클래스나 메소드를 다른 프로그램이 대신 실행해주는 것을 제어의 역전이라고 합니다.

 

DI(Dependency Injection)

DI는 의존성 주입이란 뜻을 가지고 있으며, 클래스 사이의 의존 관계를 빈(Bean) 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말합니다.

 

DI가 적용 안 된 예

개발자가 직접 인스턴스를 생성합니다.

class 엔진 {

}

class 자동차 {
     엔진 v5 = new 엔진();
}

 

 

 

Spring에서 DI가 적용된 예

엔진 type의 v5변수에 아직 인스턴스가 할당되지 않았습니다.

컨테이너가 v5변수에 인스턴스를 할당해주게 됩니다.

@Component
class 엔진 {

}

@Component
class 자동차 {
     @Autowired
     엔진 v5;
}

 

 

 

 

Spring에서 제공하는 IoC/DI 컨테이너

  • BeanFactory : IoC/DI에 대한 기본 기능을 가지고 있습니다.
  • ApplicationContext : BeanFactory의 모든 기능을 포함하며, 일반적으로 BeanFactory보다 추천됩니다. 트랜잭션처리, AOP등에 대한 처리를 할 수 있습니다. BeanPostProcessor, BeanFactoryPostProcessor등을 자동으로 등록하고, 국제화 처리, 어플리케이션 이벤트 등을 처리할 수 습니다.
  • BeanPostProcessor : 컨테이너의 기본로직을 오버라이딩하여 인스턴스화 와 의존성 처리 로직 등을 개발자가 원하는 대로 구현 할 수 있도록 합니다.
  • BeanFactoryPostProcessor : 설정된 메타 데이터를 커스터마이징 할 수 있습니다.
반응형

+ Recent posts