2020년 8월 31일 월요일

스프링5 의존성주입(DI)관련 어노테이션, @Autowired, @Scope, @Bean @Qualifier, @Required, @Value @DependsOn, @Primary, @Lazy

스프링의존성주입(DI)관련 어노테이션@Autowired, @Scope, @Bean

@Qualifier, @Required, @Value

@DependsOn, @Primary, @Lazy

 

n @Autowired

 

ü  Spring Framework에 종속적인 어노테이션.

ü  Type Driven Injection

ü  여러 개의 빈이 검색될 경우 @Qualifier(name="xxx")로 구분한다.

ü  기본적으로 @Autowired된 속성은 모두 빈이 주입 되어야 한다.

ü  (주입될 빈이 없는 경우가 있다면 required=false로 하면 오류는 발생하지 않는다.)

ü  멤버변수, setter 메소드생성자일반 메소드에 적용 가능

 

[Emp.java]

interface Emp {

          public abstract void gotoOffice();

}

 

[Programmer.java]

@Service

class Programmer implements Emp {

public void gotoOffice() {

                   System.out.println("프로그래머 출근 합니다.");

}

}

 

[Designer.java]

@Service

class Designer implements Emp {

public void gotoOffice() {

                   System.out.println("디자이너 출근 합니다.");

}

}

 

[Develope.java]

@Service

public class Develope {

          Emp emp;

          @Autowired

          public Develope(@Qualifier(value="designer") Emp emp) {

                   this.emp = emp;

          }

 

          void coding() {

                   emp.gotoOffice();

                   System.out.println("개발합니다...");

          }

}

 

n @Scope

 

ü  일반적으로 @Component, @Service, @Repository 등으로 자동 스캐닝한 자바빈은 싱글톤 형태로 하나만 생성하는데(default : @Scope가 쓰여져 있지 않을 때는 scope="singleton") 이를 변경하려면 @Scope 어노테이션을 사용하면 된다즉 빈의 범위를 설정한다.

 

 

singleton – Spring IoC 컨테이너당 하나의 빈을 리턴

prototype – 요구가 있을 때 마다 새로운 빈을 만들어 리턴

request - HTTP request 객체당 하나의 빈을 리턴

session - HTTP session 당 하나의 빈만 존재

globalSession – 포틀릿의 global Http Session 생명주기 동안 하나의 빈만 존재표준 HTTP 세션 범위 유사하며단지 포틀릿(Portlet) 기반 웹 응용 프로그램의 맥락에서 적용된다. globalSession 은 포틀릿 컨테이너를 지원한다.

 

@Component

@Scope("prototype")   //요구시마다 하나의 새로운 빈을 리턴

class Ojc {

   ……

}

 

<bean id="ojc" class="oraclejava.edu.Ojc"   scope="prototype"/>

 

 

n @Bean

 

ü  @Configuration으로 설정된 클래스의 메소드의 사용 가능.

ü  메소드가 Return 하는 객체가 Bean으로 등록된다.

ü  @Component @Configuration 없이 개발자가 작성한 클래스 위에 기술하여 그 클래스의 객체를 빈으로 만들지만 @Bean은 개발자가 만든 클래스가 아닌직접 제어 불가능한 외부 라이브러리(클래스)를 빈으로 만들 때 사용한다.

ü  @Bean 어노테이션에 name or value 속성으로 빈의 ID를 지정하지 않으면 메소드 이름을 camelCase 한 것이 빈의 ID가 된다. (첫 글자는 소문자로 이후 연결된 단어들의 첫 글자는 대문자로 표기)

 

@Configuration  //자바설정파일

class A {

@Bean(name=”makeArrayList”)

@Bean(value=”makeArrayList”)

@Bean(“makeArrayList”)

@Bean

public ArrayList<String> makeArrayList() {

                   Return new ArrayList<String>();

}

}

n  @Qualifier

ü  @Autowired에서 같은 TYPE의 객체가 여러 개인 경우 오류가 발생하는데 이러한 모호한 상황에서 사용하려는 빈을 제공하기 위해 @Qualifier를 사용한다.

 

Car 인터페이스를 구햔한 Sonata, Santafe 두 클래스가 있고 둘다 타입은 Car 이다.

@Component(“sonata”)

class Sonata implements Car{}

 

@Component(“santafe”)

class Santafe implements Car {}

 

생성자 주입

class Sonata {

@Autowired

public Sonata(@Qualifier("sonata") Car car) {

                     this.car = car;

}

}

 

세터주입

@Autowired

void setCar(@Qualifier("santafe") Car car) {

    this.car = car;

}

아래도 동일하다.

 

@Autowired

@Qualifier("santafe")

void setCar(Car car) {

    this.car = car;

}

 

필드주입

@Autowired

@Qualifier("santafe")

Car car;

 

n @Required

 

ü  Setter 메소드 위에 기술하여 필수 프로퍼티를 설정하는 용도로 사용된다.

 

package day1;

public class Emp {

   private String ename;

   @Required

   public void setEname(String ename) {      this.ename = ename;    }

   public String getEname() {      return this.ename;    }

}

 

XML설정에서(Beans.xml)…

   <context:annotation-config/>

   <bean id="emp" class="day1.Emp">

      <!-- 아래 프로퍼티를 설정하지 않으면 오류 -->

      <!-- <property ename="ename"  value="홍길동" /> -->

   </bean>

 

main에서

      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      Emp emp = (Student) context.getBean("emp");

      System.out.println(“Ename : " + emp.getEname() );

 

오류메시지  Property 'ename' is required for bean 'emp'

 

n @Value

 

ü  빈에 속성 값을 주입하기 위해 사용한다.

ü  물론 정적 값을 주입하는 것은 그다지 유용하지 않으며따라서 @Value의 자리 표시자 문자열(placeholder strings)을 사용하여 외부 소스 ( : .properties 또는 .yaml 파일)에 정의 된 값을 연결할 수 있다.

 

생성자주입

Sonata(@Value("8888") int carNum) {

    this.carNum = carNum;

}

 

세터주입

@Autowired

void setCarNum(@Value("8888") int carNum) {

    this.carNum = carNum;

}

아래와 동일하다.

 

@Value("8888")

void setCarNum(int carNum) {

    this.carNum = carNum;

}

필드주입

@Value("8888")

int carNum;

 

다른 예를 보자프로퍼티 파일에서 어떤 값을 읽어 동적으로 주입하는 경우이다.

application.properties

emp.name=scott

 

 Emp 클래스

@Component

public class Emp {

    @Value("${emp.name}")

    private String name;

 

    ……

}

 

 

n @DependsOn

 

ü  빈의 초기화 순서를 지정한다.

ü  스프링이 @DependsOn이 있는 다른 빈을 초기화 하도록 할 수 있다. DependsOn에 따라 결정되는 종속성에 의해 자동으로 수행 된다.

 

@Component

@DependsOn("engine")

class Sonata implements Car {}

 

@Bean

@DependsOn("fuel")

Engine engine() {

    return new Engine();

}

 

 

n @Primary

 

ü  @Autowired 사용시 동일한 TYPE Bean이 여러 개 있을 때 Bean에 더 높은 우선 순위를 부여하기 위해 @Primary를 사용한다. @Qualifier를 사용하여 일일이 빈의 ID를 지정해도 되지만 @Primary로 표시해 두면 @Autowired만 했을 때 @Primary로 지정된 빈이 주입된다.

ü  가장 자주 사용되는 빈을 @Primary로 표시하면 된다.

 

@Component

@Primary

class Sonata implements Car {}

 

@Component

class Santafe implements Car {}

 

@Component

class Driver {

    @Autowired

    Car car;   //Sonata 가 주입된다.

}

 

@Component

class Santafe{

    @Autowired

    @Qualifier("santafe")

    Car car;

}

 

n @Lazy

 

 

ü  스프링 빈을 느리게 초기화하고 싶을 때 @Lazy를 사용한다.

ü  기본적으로 Spring은 애플리케이션 서블릿 컨텍스트의 시작시 모든 싱글 톤 빈을 생성한다그러므로 애플리케이션 시작 시가 아니라 요청할 때 Bean을 생성해야하는 경우가 있는데 이때 @Lazy를 사용한다.

ü  @Lazy는 정확히 어디에 배치했는지에 따라 다르게 작동할 수 있다.

ü  예를 들어 어떤 빈 A가 @Lazy 때문에 느리게 로딩하려고 하지만 B클래스의 Setter에서 A를 주입 받고, B 클래스 자체는 Eager 로딩인 경우 A의 @Lazy는 작동하지 않는다.

ü  다음과 같은 경우 @Lazy가 잘 작동한다.

l  @Lazy가  팩토리 메소드의 @Bean에 위치하는 경우 메소드 호출을 지연시킨다.

@Lazy

@Bean 

Sonata sonata() {         return new Sonata();     }   //Lazy Loading

}

 

l  @Lazy가 @Configuration 클래스에 위치하는 경우 @Bean 메소드가 영향을 받는다.

@Configuration

@Lazy

class CarConfig {

    @Bean  //Lazy Loading

    Sonata sonata() {         return new Sonata();     }

}

 

l  @Lazy가 @Configuration 클래스가 아닌 @Component 클래스에 위치하는 경우 이 Bean은 느리게 초기화 된다.

@Component

@Lazy

class Sonata {

……

}

 

l  @Lazy가 @Autowired 생성자세터또는 필드에 위치하는 경우 종속성 자체를 느리게 로드한다.(프록시를 통해)

 

아래 예문은 CarConfig는 Lazy Loading이지만 sonata() 메소드는 Eager Loading을 한다.

@Configuration

@Lazy

class CarConfig {

    @Bean

@Lazy(false)

    Sonata sonata() {        return new Sonata();    }

}


#스프링강의, #스픵강좌, #스프링동영상, #스프링어노테이션, @스프링교육, #Spring어노테이션, #@Autowired, #@Scope, #@Bean, #@Qualifier, #@Required, #@Value, #@DependsOn, #@Primary, #@Lazy

댓글 없음:

댓글 쓰기

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...