@어노테이션 - [Annotation 활용하기]

728x90

[ Annotation 활용하기 ]

<빈 등록>

-우리는 지금까지 beans.xml 파일 내부에서 빈 객체를 생성/등록하고 java 코드에 해당 파일을 가져와서 사용했다.

-이제 beans.xml 파일에 등록했던 내용을 java 파일로 작업하는 방법에 대해 살펴본다.

-
xmljava파일의 차이 : xml은 값을 정해줘야 함

: java 파일은 코드를 자유롭게 작성 O

15강. [Java 코드 활용하는 Bean 등록] 

[@Configuration]

-@Configuration 어노테이션은 현재의 자바파일(.class)이 빈 등록을 위한 자바 파일임을 알려준다.

[Spring Context 생성]

       <기존 Xml파일 가져온 방식>

ClassPathXmlApplicationContext ctx = newClassPathXmlApplicationContext("kr/co/softcampus/config/beans.xml");

       <자바 파일로 등록하여 가져오는 방식>

AnnotationConfigApplicationContext ctx = newAnnotationConfigApplicationContext();
     ctx.register(BeanConfig.class);
     ctx.refresh();

[@Bean]

-@Bean 어노테이션은 bean 객체 정의/등록할 때 사용
-빈 설정 클래스에 등록한 메소드 이름 = bean 이름
-@Bean(name=이름) : bean 이름을 새롭게 정의함
-@Lazy : lazy-init 속성 지정
-@Scope :bean  scope 범위 지정
-@primary : primary 속성 지정
자바 빈은 기본적으로 싱글톤

[kr/co/softcampus/main/MainClass.java] //메인 클래스

public class MainClass {

	public static void main(String[] args) {
		//Java파일 사용하는 방식
		AnnotationConfigApplicationContext ctx2= new AnnotationConfigApplicationContext(BeanConfigClass.class);
		TestBean1 java1 = ctx2.getBean("java1", TestBean1.class);
		System.out.printf("java1: %s\n", java1);
		System.out.println("----------------");
		
		TestBean3 java3 = ctx2.getBean("java3", TestBean3.class);
		System.out.printf("java3: %s\n", java3);
		System.out.println("----------------");
		
		TestBean4 java4 = ctx2.getBean(TestBean4.class);
		System.out.printf("java4: %s\n", java4);
		ctx2.close();
	}
}

[kr/co/softcampus/config/BeanConfigClass.java] //빈 설정 클래스

@Configuration
public class BeanConfigClass { //빈 등록 설정 클래스
	
	@Bean //빈 등록하기 
	public TestBean1 java1() {
		TestBean1 t1 = new TestBean1();
		return t1;
	}
	
	@Bean
	@Lazy //이 어노테이션 붙이면 getBean할 때 빈 객체 생성됨
	public TestBean2 java2() {
		TestBean2 t2 = new TestBean2();
		return t2;
	}
	@Bean 
	@Scope("prototype") //score범위를 프로토타입으로 지정하면 매번 주소 다른 새 객체 생성됨 (싱글톤 X)
	public TestBean3 java3() {
		TestBean3 t3 = new TestBean3();
		return t3;
	}
	@Bean 
	public TestBean4 java4() {
		TestBean4 t4 = new TestBean4();
		return t4;
	}
	@Bean
	@Primary  //동일 타입의 빈 여러 개 정의되어있을 때, 사용할 빈 한정짓기
	public TestBean4 java5() {
		TestBean4 t4 = new TestBean4();
		return t4;
	}
}

[실행결과 모습]

실행결과


16강. [init, destroy 메소드]

[init, destroy 메소드]

-객체 생성/소멸될 때 자동 호출되는 메소드 등록한다.

<java 파일>
@Bean(initMethod = “bean2_init”, destroyMethod = “bean_destroy”)

[kr.co.softcampus.beans.TestBean1.java] // 빈으로 등록될 객체

public class TestBean1 {

	public TestBean1() {
		System.out.println("TestBean1의 생성자");
	}
	//이 빈 객체 생성 시 자동 호출되는 메소드 
	public void init() {
		System.out.println("TestBean1의 init메소드");
	}
	//이 빈 객체 소멸 시 자동 호출되는 메소드 
	public void destroy() {
		System.out.println("Testbean1의 destroy()");
	}
}

[kr.co.softcampus.config.BeanConfigClass.java] //빈 등록 설정 클래스

@Configuration
public class BeanConfigClass {
	@Bean(initMethod="init", destroyMethod="destroy") 
	@Lazy
	public TestBean1 java1() {
		return new TestBean1();
	}
}

[kr.co.softcampus.main.MainClass.java] // 메인 클래스

public class MainClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext(BeanConfigClass.class);
		TestBean1 java1 = ctx2.getBean("java1", TestBean1.class);
		
		ctx2.close();
	}

}
구조를 잘 보아야 한다.
(1) 객체를 등록할 class 파일 안에 init(), destroy() 메소드를 작성해준다.
(2) 빈 설정 클래스 안에서 해당 객체를 등록할 때, 빈 객체 생성 전/후에 호출될 메소드를 속성값으로 지정한다.
(3) MainClass 안에서 자바 Context 로 설정파일 등록한 뒤,
   해당 설정 파일에서 객체를 생성해보고 결과를 실행해보면 
  실제로 해당 빈 객체 생성 전/후에 등록해주었던 메소드가 호출되는 것을 콘솔창으로 확인할 수 있다. 

17강. [주입]

-주입 방식: 1) 직접 주입 방식 : 생성자/setter 메소드 직접 호출하여 값 주입

                2) 자동 주입 방식 : @Autowired


    1) 직접 주입 방식

- kr/co/softcampus/config/BeanConfigClass.java

@Configuration
public class BeanConfigClass { //빈 설정 클래스 
	@Bean
	public TestBean1 java1() {
		return new TestBean1(200, "문자열2", new DataBean1());
	}
	@Bean
	public TestBean1 java2() {
		TestBean1 t1 = new TestBean1();
		t1.setData1(400);
		t1.setData2("문자열4");
		t1.setData3(new DataBean1());
		
		return t1;
	}
}​

    2) 자동 주입 방식 

- kr/co/softcampus/config/BeanConfigClass.java

@Configuration
public class BeanConfigClass { //빈 설정 클래스 

	@Bean
	public DataBean2 data1() {
		return new DataBean2();
	}
	@Bean
	public DataBean2 data2() {
		return new DataBean2();
	}
	@Bean(autowire = Autowire.BY_NAME)
	public TestBean2 java3() {
		return new TestBean2();
	}

}

- kr/co/softcampus/main/MainClass.java

public class MainClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//스프링 컨테이너 생성 
		AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext(BeanConfigClass.class);
		
		TestBean2 java3 = ctx2.getBean("java3", TestBean2.class);
		System.out.printf("java3.data1: %s\n", java3.getData1());
		System.out.printf("java3.data2: %s\n", java3.getData2());
		
		ctx2.close();
	}
}

18강. [애노테이션 이용한 빈 설정 ]

- Spring 2.5버전부터   (1) xml 통한 빈 설정 방법
                             (2) 어노테이션을 이용한 빈 설정 방식을 제공하고 있다.

             (1) 빈 설정 파일(xml) <context:annotation-config/>

                    이 코드 추가하면 빈 설정을 (xml파일이 아닌) 빈 클래스의 어노테이션을 검색해서 반영하게 된다.

             (2) 빈 설정 파일(.java)@어노테이션 이용해서 설정 가능


[@Required]

-반드시 주입해야 할 프로퍼티로 설정한다.

-스프링 5.1버전부터는 X

-이제 반드시 주입해야 할 프로퍼티는 생성자주입을 이용하도록 변경되었다.

[@Autowired] : 객체 자동 주입 설정

-객체 타입을 통해 bean 객체 자동 주입
 
@Autowired
privateDataClass1 data3;

@Autowired
publicvoidsetData2(DataClass1 data2) {
      this.data2= data2;
}
@Autowired
publicTestBean1(DataClass2 data4) {
      this.data4= data4;
}

[@Qualifier]

-@Autowired로 자동 주입 시, 같은 타입의 Bean이 여러 개 정의되어 있을 경우 오류뜸

-이 때, @Qualifier(“한정자“) 설정하면, 스프링은 해당 bean 찾아 주입한다

ex. @Autowired
     @Qualifier(“obj1”)
     private DataClass4 data6;

[생성자 주입]

-생성자에 주입 시 객체 참조변수 타입 변수들은 자동 주입되고,

                        기본 자료형/문자열 값에 대해서는 직접 주입을 설정해주면 된다.

public TestBean2(@Value(“100”) int data1, @Value(“문자열”) String data2, DataBean data3) {
          this.data1 = data1;
          this.data2 = data2;
          this.data3 = data3;
}

-[kr/co/softcampus/config/BeanConfigClass.java]

@Configuration
public class BeanConfigClass {
		@Bean
		public TestBean1 java1() {
			return new TestBean1();
		}
		@Bean
		public DataBean1 data_bean1() {
			return new DataBean1();
		}
		@Bean
		public DataBean2 obj4() {
			return new DataBean2();
		}
		@Bean
		public DataBean2 obj5() {
			return new DataBean2();
		}
		@Bean
		public TestBean2 java2() {
			return new TestBean2();
		}
	}

-[kr/co/softcampus/beans/TestBean1.java]

public class TestBean1 {

	//필드
	private int data1;
	private DataBean1 data2;
	//자동 주입을 변수에 설정함
	//이 경우 자동으로 setter 메소드 추가되어 setter 메소드 통해 주입받게 된다.
	@Autowired
	private DataBean1 data3; //객체 빈 자동 의존 주입 
	
	@Autowired
	@Qualifier("obj4")
	private DataBean2 data4; 
//똑같은 객체 타입 2개이상 정의할 경우 자동의존주입할 빈 객체 찾을 수 없으므로 
//반드시 @Qaulifire 로 한정자 설정하여 의존할 대상 객체를 명시해야 함
	@Autowired
	@Qualifier("obj5")
	private DataBean2 data5;

	@Autowired(required = false) //있으면 주입, 없으면 주입X
	@Qualifier("obj6")
	private DataBean2 data6;
	
	//생성자
	public TestBean1() {
		
	}
	public TestBean1(int data1) {
		this.data1 = data1;
	}
	//get/set() 
	public int getData1() {
		return data1;
	}
	public void setData1(int data1) {
		this.data1 = data1;
	}
	public DataBean1 getData2() {
		return data2;
	}
	//자동 주입
	@Autowired
	public void setData2(DataBean1 data2) {
		this.data2 = data2;
	}

	public DataBean1 getData3() {
		return data3;
	}
	public DataBean2 getData4() {
		return data4;
	}
	public DataBean2 getData5() {
		return data5;
	}
	public DataBean2 getData6() {
		return data6;
	}
}

-[kr/co/softcampus/beans/TestBean2.java]

public class TestBean2 {
	//필드 
	private int data1;
	private String data2;
	private DataBean3 data3;
	private DataBean4 data4;
	
	//기본 생성자
	public TestBean2() {
		
	}
	//생성자 
  public TestBean2(@Value("100") int data1, @Value("문자열") String data2, DataBean3 data3, DataBean4 data4) {
		this.data1= data1;
		this.data2= data2;
		this.data3 = data3;
		this.data4 = data4;
	}
	public int getData1() {
		return data1;
	}
	public String getData2() {
		return data2;
	}
	public DataBean3 getData3() {
		return data3;
	}
	public DataBean4 getData4() {
		return data4;
	}
}

[실행 결과] 


19강. [JSR - 250 애노테이션 ]

[JSR-250 어노테이션]

-스프링에서 기본으로 제공되지 않지만, 자바 플랫폼 공통 어노테이션인 JSR-250 적용 가능

-이를 적용 위해서 반드시 다음의 라이브러리(의존모듈)를 추가해야 함

<dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>javax.annotation-api</artifactId>
          <version>${javax.annotation-version}</version>
</dependency>

 <빈 객체 생성 전/후에 호출되는 메소드 설정>

       ➀ 빈 설정 클래스 내부에서 @Bean(initMethod=“init1”, destroyMethod=“destroy1”)을 이용하여 설정

@Configuration
public class BeanConfigClass {
      @Bean(initMethod = "init1", destroyMethod = "destroy1")
      @Lazy //getBean 할 때 객체 만들어지도록 설정
      public TestBean1 obj1() {
            return new TestBean1();
      }
}

        우리는 JSR-250을 이용하여 해당 빈 객체 자체에 직접 등록하는 방식

[@PostConstruct] : 해당 자바 빈 객체에서 init 등록

-생성자 호출 후 자동으로 호출될 함수를 등록한다.

@PostConstruct
public void postConstruct() {
      System.out.println(“생성자가 호출된 후 자동 호출됨”);

}

[@PreDestroy] : 해당 자바 빈 객체에서 destroy 등록

-객체 소멸 전 자동으로 호출될 함수를 등록한다.

@PreDestroy
public void preDestroy() {
System.out.println(“객체 소멸되기 전 자동 호출됨”);
}

[@Resource] : 변수의 이름과 동일한 Bean의 이름을 통해 주입

@Resource
private DataClass5 data8;


@Resource(name=“obj3”)
privat DataClass5 data9;

[참고] SpringFramework 개발자를 위한 실습을 통한 입문 과정

728x90