2021년 11월 13일 토요일

스프링프레임워크 DI와 관련된 어노테이션 2-4-1. Auto-Scanning Component(Stereotyping Annotations),@Component,@Repository,@Service,@Controller,@RestController

 스프링프레임워크 DI와 관련된 어노테이션

2-4-1. Auto-Scanning Component(Stereotyping Annotations),@Component,@Repository,@Service,@Controller,@RestController

 

스프링 컨테이너는 base-package의 클래스를 검색해서 자동으로 자바 빈으로 등록하는 데 이에 해당하는 것이 @Component, @Repository, @Service, @Contoroller, @RestController 어노테이션이다.

 

자동스캔을 위해서는 <context:component-scan base-package="ojc.edu.spring" /> 과 같이 base-package를 기술하며, 패키지가 여럿인 경우 콤마로 구분하여 기술한다.

 

  • @Component : 일반적인 용도의 컴포넌트들을 표시하는 기본 스테레오 타입, 멤버변수와 getter, setter만 가지고 있는 DTO 같은 컴포넌트를 지칭한다. 스프링이 @Component 붙은 자바 클래스를 클래스패스 경로에서 자동으로 찾아 Application Context안에 이름을 부여하고 빈으로 등록한다. 빈의 기본 Scope는 songleton이며 @Scope 어노테이션으로 변경 가능하다.

@Component

//하나의 Bean 정의에 대해서 다수의 객체가 존재하며 생략하면 Singleton으로 생성된다.

@Scope("prototype")   

public class Student {

       .....

}

 

  • @Repository : 퍼시스턴스 레이어의 DAO컴포넌트에 부여하는 어노테이션, @Compone의 역할과 유사하며 DAO 메소드가 던지는 예외(Unckecked Exception)를 스프링의 DataAccessException으로 변환한다.

 

@Repository   

public class EmpRepositoryImpl implements EmpRepository {

       .....

}

 

  • @Service :  비즈니스 로직을 담고 있는 서비스 레이어의 서비스 컴포넌트를 가리키며 @Component 어노테이션과 동작은 같지만 서비스 계층의 클래스들은 @Service 어노테이션을 부여하는 것이 코드 가독성이 좋다.

 

@Service   

public class EmpServiceImpl implements EmpService {

           .....

       @Autowired

       EmpRepository empRepository;

}

 

 

  • @Controller : 프리젠테이션 레이어의 컨트롤러 컴포넌트

@Controller
public class BoardMultiController  {
 @Autowired
 private SpringBoardService springBoardService;
 ...
}

2-4-2. Context Configuration Annotations(@Scope,@Autowired,@Resource,@Inject,@Required,@Named,@Order,@PostConstruct,@PreDestroy)

 

  • @Scope : 일반적으로 @Component, @Service, @Repository 등으로 자동 스캐닝한 자바빈은 싱글톤 형태로 하나만 생성하는데 이를 변경하려면 @Scope 어노테이션을 사용하면 된다. 즉 빈의 범위를 설정한다.

 

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

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

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

session - HTTP session 당 하나의 빈을 리턴

globalSession - 전체 모든 세션에 대해 하나의 빈을 리턴

 

@Component

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

class Ojc {

   ……

}

 

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

 

빈을 주입 받는 경우 아래의 어노테이션이 사용 가능하다.

 

  • @Autowired

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

빈의 id, name로 아무거나 맞으면 적용(Type Driven Injection)

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

기본적으로 @Autowired된 속성은 모두 빈이 주입되어야 한다. (주입될 빈이 없는 경우가 있다면 required=false로 하면 오류는 발생하지 않는다.)

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

 

  • @Resource

Spring2.5 이상에서 사용가능하며 Spring Framework에 비종속적으로 권장하는 방식이다.

빈의 name으로 주입될 빈을 찾는다.

멤버변수, setter 메소드에 적용가능

사용하기 위해서는 jsr250-api.jar가 클래스패스에 추가되야 한다.

 

[MAVEN 설정]

<dependency>

<groupId>javax.annotation</groupId>

<artifactId>jsr250-api</artifactId>

<version>1.0</version>

</dependency>

 

  • @Inject

Spring3.0 이상에서 사용가능 하다.

특정 Framework에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다.

JSR.330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 한다.

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

 

[MAVEN 설정]

<dependency>

<groupId>javax.inject</groupId>

<artifactId>javax.inject</artifactId>

<version>1</version>

</dependency>

 

  • @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'

 

 @Required 어노테이션이 사용되기 위해서는 RequiredAnnotationBeanPostProcessor 클래스를 빈으로 등록하거나 <context:annotation-config> 설정을 추가하면 된다.

 

  • @Named : JSR-330의 어노테이션이며 Spring의 @Component, @Qualifier와 동일하다.

 

@Repository                       @Named

public class EmpDAO { … }          public class EmpDAO { … } 

 

@Service                          @Named

public class EmpService { … }        public class EmpService { … }

 

@Component                      @Named

public class EmpVO { … }            public class EmpVO { … }

 

@Autowired

public void setEmp(@Qualifier(“programmer") Emp emp) { … }

 

아래와 동일

 

@Inject

public void setEmp(@Named(“programmer") Emp emp) { … }

 

[MAVEN 설정]

<dependency>

<groupId>javax.inject</groupId>

<artifactId>javax.inject</artifactId>

<version>1</version>

</dependency>

 


 

EHiOAWnRKqVbt-6jvvxPk42E-xMSSkVrSRF_kvm0


 

  • @Order

Spring4에서 새로 소개된 @Order 어노테이션은 같은 타입의 빈이 컬렉션(List등)에 Autowired 될 때 그 순서를 지정한다.(낮은 숫자가 우선순위가 높다)

 

먼저 @Order를 사용하지 않은 예제를 작성해 보자.(스프링 버전은 4이상으로)

 

[Emp.java]

package ojc;

public interface Emp {

public void work();

}

 

[Programmer.java]

package ojc;

import org.springframework.stereotype.Service;

@Service

public class Programmer implements Emp {

public void work() {

System.out.println("Programmer Working...");

}

}

 

 

[Designer.java]

package ojc;

import org.springframework.stereotype.Service;

@Service

public class Designer implements Emp {

public void work() {

System.out.println("Designer Working...");

}

}

 

[OrderTest.java]

@Service

public class OrderTest {

@Autowired

List<Emp> emps;

public static void main(String[] args) {

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

OrderTest test = (OrderTest) context.getBean("orderTest");

for(Emp e : test.emps) {

e.work();

}

}

}

 

[/src/main/resources/order.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"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">

<context:component-scan base-package="ojc"/>

</beans>


 

OrderTest를 실행하면 다음과 같이 결과가 나타난다.(Designer가 List에 먼저 주입됨)

 

[실행 결과]

Designer Working...

Programmer Working...

 

그러나 emps 리스트에 주입되는 빈에 순서가 정의되지 않는다. 이때 주입되는 순서를 주기 위해 @Order를 사용하면 된다. 물론 XML설정을 이용하여 Programmer, Designer를 빈으로 등록해 놓고 List<Emp> emps의 setter를 이용하여 Collection 형태로 빈을 주입한다면 기술된 빈의 순서대로 List에 들어가게 된다.  앞 예제를 수정해 보자.

 

[Designer.java]

@Service

@Order(value=2)

public class Designer implements Emp }

 

[Programmer.java]

@Service

@Order(value=1)

public class Programmer implements Emp { … }

 

이제는 Programmer가 우선순위가 높아 먼저 출력될 것이다.

 

  • @PostConstruct

객체가 생성된 후 별도의 초기화 작업을 위해 실행하는 메소드를 선언한다.

CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시키거나 <context:annotation-config> 태그를 사용하면 된다.

 

class Hello {

   String name = null;

   Hello(String name) {

      this.name = name;

   }

   @PostConstruct

   public initObj() {

      if (name == null) {

         name = "홍길동";

      }

   }

}

 

  • @PreDestroy

스프링 컨테이너에서 객체(빈)를 제거하기 전에 해야할 작업이 있다면 메소드위에 사용하는 어노테이션 이다. 이 어노테이션을 사용하기 위해서는 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록하거나 <context:annotation-config> 태그를 사용하면 된다. 

 

#스프링어노테이션, #스프링DI, #@PreDestroy, #@Inject, #@Autowired, #@Component, #@Repository, #@Service, #@Controller

(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...