@Component 어노테이션을 이용하면 Bean Configuration 파일에 Bean을 따로 등록하지 않아도 사용할 수 있다.

빈 등록자체를 빈 클래스 자체에다가 할 수 있다는 의미이다.

 

@Component 어노테이션은 기본적으로 타입기반의 자동주입 어노테이션이다. 

@Autowired, @Resource와 비슷한 기능을 수행한다고 할 수 있겠다.

 

@Component 어노테이션을 xml 설정파일에서 설정하는 방법이다.

 

 

 

 

 

 

 

1. Xml 설정파일에서 @Component 어노테이션 설정하기

 

xml파일에 <context:component-scan base-package="패키지경로" /> 태그를 설정해주면, 지정된 패키지 안에 있는 bean클래스의 어노테이션을 분석할 수 있도록 지정해주는 것이다.

 

설정한 패키지 경로 안에 bean클래스를 만들고 @Component 어노테이션을 붙여주면 해당 bean클래스는 자동으로 빈이 생성될 수 있게 된다.

 

아이디를 사용하지 않고 타입으로 빈을 지정해서 찾는거랑 비슷한 느낌이다... 이름이 없기 때문에 타입으로서 빈을 받아낼 수 있다.

 

 

 

이렇게 패키지를 등록해주고 패키지 아래에 comBean1 이라는 클래스를 만들어서 @Component 어노테이션을 붙여주었다.

 

 

 

그 후 실행해보면, 별다른 빈을 등록하지 않아도 comBean1클래스가 빈에 등록되어 있다는것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

2. java configuration 파일에서 @Component 설정하기

 

xml에서 설정한 것을 당연히 자바 configuration 파일에서도 할 수 있다.

 

@Configuration 어노테이션 아래에 @ComponentScan(basePackages="패키지 경로") 이라는 어노테이션을 써줌으로써 해당 패키지안에 있는 bean클래스의 어노테이션을 분석할 수 있도록 설정해줄 수 있다.

 

javacb1이라는 빈을 만들어서 패키지안에 등록되어 있는 bean클래스(comBean 클래스) 를 return하는 빈을 등록해준다.

이 빈을 메인에 출력해보면, 

 

 

 

 

다음과 같이 그냥 comBean1.class를 가져오는것 만으로도 빈을 가져올 수 있다.

@Component 어노테이션은 타입기반으로 빈을 등록해주는 놈이라서 이름을 써주지 않고 클래스만 넣어주면 된다.

 

 

 

 

 

 

 

 

3. @Component

 

위에서 설명했던것 처럼 @Component는 타입을 통해 등록된 Bean객체를 가져올 수 있다.

또한 IoC컨테이너 객체를 생성할 때 자동으로 객체가 생성되며, Singleton이다.

 

 

 

 

 

 

기본생성자를 만들고 실행해서 생성자가 언제 호출되는지를 확인해보았다.

getBean하여 객체를 가져오기 전에 comBean1클래스의 기본생성자가 호출된 모습을 볼 수 었다.

또한, 빈 객체의 범위는 싱글톤이기 때문에 객체를 두번 호출하면 같은 객체가 출력되는것을 확인하였다. 

 

 

 

 

 

 

 

4. @Component("빈 이름")

 

@Component 어노테이션도 빈을 설정하는 어노테이션이기 때문에 빈의 이름을 따로 정해줄수도 있다. 괄호열고 빈이름을 적어주면 된다. 그런데 @Component는 특징이 있다.

 

한개의 패키지 내에서 여러개의 이름으로 빈을 등록하는 것이 불가능하다는 것이다.

 

@Component는 이름을 셋팅할 때 쓴다기보다는 이름이 없이 딱 타입을 통해서 가지고 오는 빈들... 즉, 전체 프로그램에서 특정 클래스타입의 빈을 딱 한번 등록해서 사용할 경우에 사용된다.

 

같은 클래스 타입으로 여러개의 이름으로 빈을 등록하려면 xml파일을 이용하거나 java configuration 파일을 이용해서 빈을 여러개 정의해주면 되겠다.

 

 

 

이로 인해서 @Bean 과 @Component 를 사용해야 할 경우를 다음과 같이 비교해볼 수 있다.

 

- @Bean :             개발자가 Class코드를 수정할 수 없을 때

                           같은 클래스 타임의 Bean을 여러개 등록할 때

 

- @Component   개발자가 Class코드를 수정할 수 있을 때

 

 

 

 

다음과 같이 이름을 "test"라고 지정하고 @Component를 사용하였다. 

 

 

 

 

이렇게하면, test라는 이름으로 빈을 가져오는것이 가능하다.

위에서 말했듯이 @Component를 사용하면 빈의 이름을 같은 패키지 안에서 여러개 지정할 수 없다..

@Component("test1", "test2")와 같은 형태는 존재하지 않는다는 것이다.

 

따라서, 같은 타입의 빈 클래스를 여러개이름을 부여하여 사용하기 위해서는 java configuration 파일을 사용한다. 

 

 

 

 

 

 

 

5. @Component 의 여러 가지 설정

 

 

@Component

@Lazy

-> getBean을 할 때 객체를 생성하는 Lazy속성이다. 

 

 

@Component

@Scope("prototype")

-> Default가 싱글톤으로 설정된 객체 생성에 범위를 prototype으로 바꾸어준다. 이렇게 하면 객체가 생성될때마다 새로운 객체가 생성된다.

 

 

 

@PostConstruct, @PreDestroy

-> @Component로 설정된 bean클래스에 @PostConstruct, @PreDestroy 어노테이션이 설정되어 있는 메소드는 각각 객체가 생성되기 전에 호출되는 메소드, 객체가 소멸된 후에 호출되는 메소드로 지정된다.

@Bean을 사용할때는 initMethod="initmethod" 와 같이 빈을 만들때마다 생성을 해주어야 했지만 @Component에@PostConstructor, @PreDestroy을 설정하면 객체가 생성되기 전 후로 메소드를 계속 호출 가능하다.

 

 

 

 

 

 

 

 

6. @Component 의 자동주입 

 

@Component어노테이션을 사용하여 자동주입하는것은 @Bean 어노테이션을 이용하는 것과 동일하다..

예제를 보며 한개한개 살펴보자.

 

 

@Autowired

-> 타입을 통한 자동주입이다. 변수에 설정해주면 자동으로 타입에 맞는 빈을 찾아서 setter를 통한 주입을 해준다.

 

 

@Qualifier("빈 이름")

-> 이름을 통한 자동주입이다. @Autowired 와 함께 써준다. 

@Component("obj1") 어노테이션을 이용하여 obj1이라는 이름의 빈을 생성하였다고 한다면, @Qualifier("obj1") 을 사용해서 이름을 통한 자동주입을 해준다.

 

 

@Resource(name="빈 이름")

-> JSR-250 에서 제공하는 어노테이션으로 @Autowired @Qualifier("빈 이름") 과 같은 역할을 한다. 동작은 위와 동일하게 하겠다.

 

 

생성자를 통한 주입

-> @Component 어노테이션을 사용하여 빈을 등록한 comBean1과 comBean2가 있다고 하자.

TestBean1이라는 클래스의 생성자에서 저 두 타입의 빈을 주입한다고 하면, 

 

이런식으로 해주면 되겠다. 별다른 설정없이 타입을 기반으로 빈을 찾아서 생성자를 통해 주입을 해준다. 

예전에 @Required라는 어노테이션을 설명한적이 있다. 이는 반드시 값을 주입해야하는 프로퍼티를 설정하는 어노테이션으로써, @Required를 setter에 붙이면 반드시 setter를 통해 값을 주입해야하는 역할을 하는 어노테이션이었다.

 

그런데 spring5.1 부터는 @Required를 사용하지 않는다. 

반드시 주입해야할 프로퍼티가 있다면 위의 예제와 같이 @Component로 빈을 등록하고(사실 @Autowired를 사용해도 상관은 없다.) 생성자를 통해서 값을 주입하는것을 더 권장한다.

 

 

 

int, String과 같은 기본형은 자동주입을 해줄수 없으므로 @Value 어노테이션을 이용하여 값을 지정할 수 있다.

'JAVA > Spring' 카테고리의 다른 글

execution 명시자  (0) 2020.04.17
AOP  (0) 2020.04.17
JSR-250 어노테이션  (0) 2020.04.11
Annotation을 이용한 빈 설정  (0) 2020.04.11
Java를 이용한 Bean 객체 주입  (0) 2020.04.10

JSR-250은 자바플렛폼 공통 어노테이션이다. 기본 자바에서는 제공하지 않기 때문에 적용을 위해서는 라이브러리를 반드시 추가해야 한다. 

JSR-250 어노테이션 종류는 @Resource, @PostConstruct, @PreDestroy가 있다.

 

 

JSR-330 에서는 @Autowired 및 @Qualifier 어노테이션과 비슷한 @Inject  @Named 어노테이션이 있는데 이는 추후에 포스팅하도록 하겠다.

오늘은 JSR-250 어노테이션에 대해서 알아보자.

 

 

 

 

 

먼저, 의존성을 추가해보자

 

 

mvnrepository에서 jsr 250이라고 검색하면 다음과 같은 화면이 나온다.

Maven부분을 복사해서 pom.xml에 의존성을 추가하였다. 

 

 

version이 바뀔 수도 있기 때문에 javax.annotation-version이라는 이름의 변수로 따로 빼주었다.

 

 

 

 

 

 

 

 

1. @Resource

 

 

이렇게 @Autowired와 @Qualifier 어노테이션을 이용해서 타입기반의 bean을 자동주입할 때, id에 따라서 각각 주입할 수 있도록 설정해주었다. 

@Resource 어노테이션은 이걸 하나로 합쳐서(?) 사용할 수 있는 어노테이션이다.

 

 

 

빈 설정파일에 다음과 같이 data1, data2 라는 이름의 빈이 등록되어 있다고 하면, 

 

 

 

이렇게 @Resource(name="빈 이름") 어노테이션을 이용하여 타입기반으로 자동주입을 하지만 id로 빈을 찾아주어 주입할 수 있다. 

 

 

 

 

 

 

 

 

 

2. @PostConstruct 과 @PreDestory

 

 

 

TestBean 파일에 다음과 같이 init() 메소드와 destroy() 메소드를 정의해주고 

 

 

 

 

설정파일에서 Bean을 등록할때 다음과 같이 @Bean(initMethod="init", destroyMethod="destroy") 어노테이션을 이용하여 빈을 등록하면 객체가 생성되기 전에 init메소드가 호출되고, 객체가 소멸될 때 destroy메소드가 호출되도록 설정할 수 있었다.

 

 

@PostConstruct 과 @PreDestory 어노테이션을 이용하면 @Bean을 사용하여 빈을 등록할때 번거롭게 메소드들을 등록해주지 않아도 된다.

 

 

 

 

TestBean파일에서 init메소드와 destroy메소드를 정의할때 @PostConstruct 과 @PreDestory 어노테이션을 붙여서 정의해주면 자동으로 객체가 생성되기 전과 소멸될 때 메소드가 호출되도록 설정할 수 있다.

'JAVA > Spring' 카테고리의 다른 글

AOP  (0) 2020.04.17
@Component 어노테이션  (0) 2020.04.15
Annotation을 이용한 빈 설정  (0) 2020.04.11
Java를 이용한 Bean 객체 주입  (0) 2020.04.10
Java코드를 활용한 Bean 등록  (0) 2020.04.10

어노테이션(Annotation) 이란???

 

 

앞에서도 @Bean과 같은 어노테이션을 사용하여 포스팅 하기는 했지만 정확히 어노테이션이 어떤것인지에 대한 설명이 없었던것 같다..

 

Annotation 의 사전적 의미는 '주석'이다. 

자바에서는 // 또는 /**/ 과 같이 코드에서 실제 동작하지 않는 즉, 의미가 없는 부분을 주석이라고 한다.

어노테이션도 마찬가지이다. @를 사용한 주석이다. 어노테이션 자체로 어떠한 동작을 하는것은 아니지만 어노테이션을 써줌으로써 자바코드에 '주석'을 달아 특별한 의미를 부여한 것을 의미한다.

 

' 프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공, 코드에 정보를 추가하는 정형화된 방법.

출처: https://sjh836.tistory.com/8 [빨간색코딩]

 

 

자바코드에서 이러한 어노테이션을 이용하여 빈을 설정하는 방법에 대해서 알아보도록 하자.

 

 

 

 

 

 

 

1. @Required

 

Required 어노테이션은 반드시 주입해야 할 프로퍼티를 설정하는 어노테이션이다.

POJO클래스의 setter메소드에 @Required를 설정해주면 필드 데이터는 null이면 안되고, 무조건 setter를 이용하여 값을 주입해주어야 한다. (xml 파일에서 bean을 등록할 때 해당되는 내용)

 

그러나 ...

 

Spring 5.1 이후부터는 더이상 @Required를 쓰지 않는다..

반드시 입력해야 하는 값은 @Required 어노테이션을 사용하지 않고 생성자를 이용한 주입으로 해주어야 한다...

예를들어, 매개변수가 없는 생성자를 만들지 말고 매개변수로 data를 받는 생성자를 만들면 객체를 만들때 무조건 데이터를 넣어주어야 하기 때문에 이와 같이 사용한다.

 

 

 

어노테이션을 사용하기위해서는 다음과 같이 xml을 조금 수정해야한다.

xmls:context 속성을 추가해야하고, xsi:schemaLocation속성에 context를 추가해야 하며 

<context:annotation-config/> 태그를 추가해 주어야 한다.

외우기보다는 추가해야한다고 알아두면 되겠다..

 

 

req라는 이름의 bean을 추가해준다. 

 

 

 

TestBean9클래스의 setter에 다음과 같이 @Required어노테이션을 추가해 준 후 컴파일,실행 해보면

 

 

오류....  값을 무조껀 넣어주어야 하기 때문이다.

 

 

 

다음과 같이 property 속성을 이용하여  data1에 값을 넣어준 후 실행해보면

 

 

 

오류가 나지 않고 실행이 되는 것을 볼 수 있었다.

 

 

 

 

 

 

 

 

2. @Autowired

 

@Autowired는 타입기반 자동주입 설정이다. 

예를들어, POJO클래스의 setter메소드에 @Autowired 설정을 해주면 setter에 들어갈 매개변수의 타입과 같은 빈을 찾아서 자동으로 주입해준다. 

이 때, 설정파일(xml 또는 java파일)에는 자동주입이 될 빈이 (..당연하게도) 정의가 되어있어야 한다.

 

@Autowired는 변수에도 설정이 가능하다.

자동주입을 변수에 설정하는것으로 자동으로 setter메소드가 추가되어 setter메소드를 통해 주입을 하게 된다. 데이터를 꺼내올 getter만 정의하여 사용하면 되겠다. 

 

 

xml과 비슷하기 때문에 자바파일에서 빈 등록하는 예제만 해보겠다.

setter에 설정하는거말고 변수에 설정하는 예제로 해보자.

 

 

 

 

TestBean9을 재활용했다. DataBean2 타입의 data2를 추가하였는데, @Autowired로 설정해주고 getter 메소드만 만들어주었다. setter메소드는 어노테이션을 써줌으로서 자동으로 생성되기 때문이다. 

 

 

 

bean 설정파일에는 다음과 같이 빈을 등록해 주었다.

@Autowired는 타입 기반으로 자동주입을 해주기 때문에 bean의 이름은 상관이 없다. anything으로 설정했다.

그리고 auto라는 이름으로 TestBean9 형태인 빈을 만들었다.

 

 

 

그리고 다음과 같이 getBean한 후, 그 빈의 getData2해서 DataBean2형태의 빈이 자동으로 잘 주입되었는가 출력을 해보았다.

 

 

 

 

성-------------공

 

 

 

 

 

 

 

 

3. @Qualifier

 

@Qualifier 어노테이션은 @Autowired의 짝꿍이다. @Autowired 어노테이션은 타입기반으로 자동주입을 해주는 어노테이션임을 위의 예제에서 알아보았다. 만약 자동주입을 해야하는 빈중에서 같은 타입의 빈이 여러개 있으면 @Autowired를 써주어도 에러가 날 것이다.

 

이때 써주는 어노테이션이 @Qualifier이다. 타입이 같은 빈이 여러개 있으면 id로써 자동주입하는 빈을 찾아주는 어노테이션이다. 

@Qualifier("빈의 이름") 형태로 써준다.ㄴ

 

 

 

TestBean9 클래스에 DataBean2형태의 변수를 한개 더 선언해준다.

 

 

2번의 예제와 똑같이 구성되어 있는 예제파일에서 빈 설정파일이 위와 같이 되어 있다고 가정하자.

@Autowired 어노테이션은 타입기반 자동주입이기 때문에 이름이 상관없다고 했었다. 그런데 저렇게 같은 타입의 빈이 2개 이상이 되면 어떤 빈을 넣어야할지 모르기 때문에 에러가 발생한다.

 

 

 

@Qualifier 어노테이션을 이용해서 빈의 id를 설정해주었다.

 

 

 

 

성---------------------공

 

 

 

 

 

 

4. 생성자를 통한 주입

 

xml에서 bean을 설정할때 사용하는 방법에 대애서 먼저 알아보도록 하겠다.

1번 예제에서 처럼 xml파일에 어노테이션을 이용한 빈을 등록하기 위해서는 <context:annotation-config/> 을 포함하여 xml파일의 속성을 조금 바꾸어 주어야 한다고 설명하였다.

xml파일에서 생성자를 통하여 빈을 자동주입하면 참조변수 타입은 자동으로 주입되고, 기본 자료형 및 문자열은 사용자가 설정해주어야 한다.

 

 

 

 

TestBean10을 다음과 같이 구성하였다. 생성자에는 매개변수로 DataBean와 DataBean2 형태인 변수를 받는다.

 

 

 

 

xml 파일에 다음과 같이 bean을 등록해준다.

id값이 없는 DataBean형의 bean과 DataBean2형의 bean이 등록이 되어있고, 

TestBean10형의 bean이 autoCon이라는 id를 가지고 등록되어 있다. autoCon에는 따로 아무 설정도 해놓지 않았다.

 

이렇게 xml파일을 구성하면 <context:annotation-config/> 설정덕분에 생성자의 타입을 보고 일치하는 타입을 자동으로 주입해준다. 

 

 

 

 

 

data1과 data2는 주입해준게 없으니까 아무값도 들어가지 않고, data3과 data4는 객체가 자동으로 주입되어 실행되는 모습을 볼 수 있었다.

 

data1과 data2를 객체가 생성될 때 설정해주려면 @Value태그를 쓰면 된다.

 

 

 

 

 

다음과 같이 생성자에 @Value 어노테이션을 넣어 직접 주입해준 후 실행해보면 

 

 

 

이와 같은 결과를 얻을 수 있다.

'JAVA > Spring' 카테고리의 다른 글

@Component 어노테이션  (0) 2020.04.15
JSR-250 어노테이션  (0) 2020.04.11
Java를 이용한 Bean 객체 주입  (0) 2020.04.10
Java코드를 활용한 Bean 등록  (0) 2020.04.10
자동 주입  (0) 2020.04.10

java파일을 이용하여 bean객체를 만들고 주입하며, 자동주입은 어떻게 하는지 알아보도록 하자.

 

 

 

일단 기본적으로 예제에 사용할 TestBean7을 위와 같이 정의하였다.

 

 

 

 

 

 

1. 생성자를 이용한 주입

 

 

위와 같이 설정해주면 된다. 뭔가 간단한거 같다....

그냥 원래 자바파일에서 생성자에 매개변수 넣어주듯이 하면 된다. 

생성자의 매개변수를 한개씩 사용자가 넣어주는 예제이지만 FileStream하여 파일에서 읽어올 수도 있겠고, 웹이라면 Request하여 읽어올 수도 있을것 같다!!

 

 

 

이렇게 하면 정상적으로 출력된다. 

 

 

 

 

 

 

 

 

2. setter를 이용한 주입

 

 

 

이것도 뭐 간단하다.

너무도 당연하게 setter에 직접 데이터를 넣어주는 방식이다. 변수를 여러가지로 활용할 수 있겠다.

main의 출력코드는 생략하겠다.

 

 

 

 

 

 

 

 

3. 자동주입

    3-1. Autowire.BY_NAME

 

 

TestBean8은 DataBean2 타입인 data1과 data2 2개가 있다.

 

 

 

이름으로 객체를 찾아서 자동으로 주입해주는 것은 java파일에서는 위와 같이 설정한다.

DataBean2 형의 필드와 이름이 똑같은 data1과 data2를 bean으로 등록해준다.

 

TestBean8 타입의 di3을 정의해주는데 @Bean(autowire = Autowire.BY_NAME) 어노테이션으로 설정하여 이름으로 객체를 자동주입할 수 있도록 해준다.

 

 

 

 

결과는 아주 잘 나온다..

 

 

 

 

 

 

 

 

 

    3-2. Autowire.BY_TYPE

 

 

type이 같은 빈을 찾아서 자동으로 주입해주는 어노테이션 설정이다. 어짜피 타입으로 찾기때문에 메소드의 이름은 중요하지 않을것이다. data100이라고 그냥 대충 정해봤다.

 

그후 di4를 정의하는데 @Bean(autowire = Autowire.BY_TYPE) 어노테이션을 이용하여 타입으로 객체를 찾아 자동주입하도록 설정하였다.

 

 

 

 

잘 나오는 것을 확인하였다.

'JAVA > Spring' 카테고리의 다른 글

JSR-250 어노테이션  (0) 2020.04.11
Annotation을 이용한 빈 설정  (0) 2020.04.11
Java코드를 활용한 Bean 등록  (0) 2020.04.10
자동 주입  (0) 2020.04.10
컬렉션 주입  (0) 2020.04.09

지금까지는 bean을 등록하기 위해서 beans.xml 이라는 xml파일을 계속해서 사용해왔다.

이는 spring버전의 발전에 따라 xml파일에서 뿐만 아니라 java코드에서 bean을 등록할 수도 있도록 바뀌었다.

(그리고, 이게 더 많이 쓰인다고 한다...)

 

지금까지 했던 bean등록의 여러가지 방법을 java파일에서는 어떻게 활용하면 되는지 알아보자!!

 

 

 

 

 

 

 

 

1. java파일을 bean등록파일로 만들기

   (@Configration , @Bean)

 

 

java 파일에서 bean을 등록하기 위해서는 @Configration이라는 어노테이션을 클래스에 붙여준다.

그리고 xml파일에서 bean태그를 이용하여 빈을 등록해 주었듯이 @Bean 어노테이션을 이용하여 메소드로써 정의해주면 된다.

 

 

 

TestBean6 라는 클래스가 정의되어 있다고 치자.

 

 

 

위와 같이 빈 등록 파일을 JavaBean이라는 자바파일로 만들었다.

java1이라는 메소드를 @Bean 어노테이션을 이용하여 정의하였는데 bean의 id값이 바로 메소드의 이름이 된다.

xml파일과 동일하게 다른 설정을 해주지 않으면 default값은 singleton이다.

 

 

 

 

 

main도 조금 달라졌다.

ClassPathXmlApplicationContext를 사용하여 xml을 불러왔었는데, 자바를 사용할때는 

AnnotationConfigApplicationContext를 사용하여 자바클래스를 불러온다. xml파일은 해당파일의 path를 다 적어주어야 하지만 자바클래스는 위와같이 JavaBean.class와 같이 적어주면 된다.

 

 

 

 

 

 

 

 

2. Bean의 이름 설정해주기

   (@Bean(name="빈 이름"))

 

 

위에서 bean의 id값은 메소드의 이름이라고 설명하였다. 메소드의 이름을 건드리지 않고 빈의 이름을 설정하는 방법이 있다.

 

 

 

위와 같이 빈의 name속성을 바꾸어주면 메소드의 이름을 바꾸지 않고 손쉽게 빈의 이름을 변경할 수 있다.

 

 

 

 

 

 

 

 

 

3. 여러가지 bean 설정들

   (@Lazy, @Scope("singleton/prototype"), @Primary)

 

 

xml에서 사용했던 설정들을 java파일에서도 그대로 다 사용할 수 있다. 모두 어노테이션을 이용하여 설정한다.

 

 

 

@Lazy 어노테이션은 xml의 lazy-init 속성과 같다. @Lazy를 설정하면 lazy-init이 true값이 되며, getBean을 해야 객체를 생성한다.

 

@Scope("prototype") 어노테이션은 안써주면 default값은 singleton이다. @Scope("prototype")을 써줌으로써 getBean으로 객체를 새로 생성할 때마다 서로 다른 객체가 생성된다.

 

@Primary 어노테이션은 bean의 id가 설정되어 있지 않을 때 사용한다. 같은 type의 빈이 여러개 설정되어 있을 때, @Primary 어노테이션이 설정되어 있는 bean이 우선으로 불러와진다.

 

 

 

 

 

 

 

 

 

4. init, destroy 메소드 설정하기

   (@Bean(initMethod="init메소드", destroyMethod="destroy메소드"))

 

 

xml에서는 init메소드나 destroy메소드를 사용하기 위해서는

intit-method="init메소드" 이나 destroy-method="destroy메소드" 를 사용하였다. java도 비슷하다.

@Bean 어노테이션에 설정에 @Bean(initMethod="init메소드", destroyMethod="destroy메소드") 와 같이 설정해주면 된다.

 

 

 

TestBean6 클래스에 다음과 같이 init이라는 메소드와 destroy라는 메소드를 정의하였다.

 

 

 

자바 빈 설정파일에 java2라는 메소드를 정의하였으며 @Bean 어노테이션의 속성을 위와 같이 설정하여 init메소드와 destroy메소드를 설정하였다. 

 

 

 

 

main에서 돌리면 다음과 같이 bean객체가 생성되기 전과 후에 각각 init메소드와 destroy메소드가 정상적으로 호출된 것을 볼 수 있었다.

'JAVA > Spring' 카테고리의 다른 글

Annotation을 이용한 빈 설정  (0) 2020.04.11
Java를 이용한 Bean 객체 주입  (0) 2020.04.10
자동 주입  (0) 2020.04.10
컬렉션 주입  (0) 2020.04.09
의존성 주입 (Dependency Injection)  (0) 2020.04.09

지금까지는 xml을 이용해서 생성자, setter를 사용한 주입을 알아보았다.

빈 객체를 한개한개씩 아이디 지정하여 넣어주지 않아도 자동으로 주입할 수 있는 자동 주입에 대해서 알아보겠다.

 

자동주입은 기본 자료형에서는 동작하지 않고, 사용자 지정 객체타입에서만 동작한다.

특정클래스를 가지고 만든 객체의 주소값을 담는 참조변수같은 경우 자동으로 주입 가능하는 뜻이다!!

 

 

 

 

1. 이름을 통한 주입

 

이름을 통한 주입을 하기위해서는 bean태그의 속성에 autowire="byName" 를 추가해 주면 된다. 어떤식으로 사용해야 자동으로 주입을 해주는지 코드를 살펴보자.

 

 

 

 

다음과 같이 TestBean4라는 이름의 클래스를 정의하였다.

 

 

id가 data1, data2인 빈을 정의한 후, autowire="byName" 이라는 속성을 넣어주면 이름으로 빈을 찾아서 자동으로 TestBean4의 data1, data2에 각각 주입을 해준다. 

 

 

 

실행하면 정상적으로 출력되는 모습을 볼 수 있었다.

 

 

 

 

 

 

 

2. 타입을 통한 주입

 

타입을 통한 주입을 하기위해서는 bean태그의 속성에 autowire="byType" 를 추가해 주면 된다.

 

 

 

다음과 같이 TestBean5를 정의하였다.

 

 

 

클래스 타입으로 찾을 것이기 때문에 굳이 id를 설정해주지 않았다.

DataBean2 타입으로 만들어진 bean이 있고, auto2에 autowire="byType"하였기 때문에 빈의 타입으로 알아서 자동주입된다.

 

 

 

실행하면 정상적으로 출력되는 모습을 볼 수 있었다.

'JAVA > Spring' 카테고리의 다른 글

Java를 이용한 Bean 객체 주입  (0) 2020.04.10
Java코드를 활용한 Bean 등록  (0) 2020.04.10
컬렉션 주입  (0) 2020.04.09
의존성 주입 (Dependency Injection)  (0) 2020.04.09
Bean 객체의 생성시점과 생명주기  (0) 2020.04.08

자바의 컬렉션 중에서 List, Set, Map, Properties 4개의 타입은 어떻게 주입이 되는지 알아보겠다.

 

 

 

 

TestBean3라는 포조클래스에 위와 같이 필드를 선언하고 모든 필드에 대해서 getter, setter를 선언해주었다.

앞에 글에서 사용한 setter를 이용한 주입으로 자바 컬렉션 타입들에 주입을 시도해볼 것이다.

 

 

 

xml 파일에서 각각의 컬렉션타입의 setter주입을 할때, 이미 정의되어 있는 bean을 불러와서 사용할 때는 아래의 beans_data라는 이름의 bean을 공통적으로 사용하겠다.

 

 

 

 

 

 

 

 

1. List

 

 

bean1 이라는 빈 태그 안에 property 태그를 사용하여 setter주입을 시도한다.

List타입이기때문에 List태그 사용하고, 그 태그 안에 value태그를 이용하여 제네릭타입에 맞는 value값을 주입해준다.

 

최우선순위인 String형은 default의 느낌이라서 type정의를 안해주어도 상관없지만, 

int와 같은 다른 기본형들은 꼭 셋팅을 해주는 것이 좋다.

 

DataBean형인 List에 값을 넣는 "list3"의 경우,

주입할 bean을 직접 bean태그를 이용해서 넣어도 되고, ref bean을 이용하여 미리 정의되어 있는 beans_data를 넣어주어도 된다. beans_data는 prototype이므로 넣을 때마다 새로운 객체가 생성되겠다. 

 

 

 

다음과 같이 실행하면

 

 

이런결과를 얻을 수 있다.

 

 

 

 

 

 

 

2. Set

 

 

 

bean1 이라는 빈 태그 안에 property 태그를 사용하여 setter주입을 시도한다.

Set타입이기때문에 Set태그 사용하고, 그 태그 안에 value태그를 이용하여 제네릭타입에 맞는 value값을 주입해준다.

방법과 형태는 List와 똑같다.

 

 

Set은 중복된 값을 하나의 값으로 생각하여 한개만 넣는 특징이 있다.

그래서 위와 같이 여러개 같은 값을 찍어도, 

 

 

 

 

이렇게 한개만 출력된다.

<ref bean="beans_data" /> 를 두번찍었고, scope도 prototype이라서 다른 추가할 때마다 객체가 생성될것 같지만

id값이 동일한 bean이기 때문에 한개로 인식해서 한개만 출력한다.

 

 

 

 

 

 

 

3. Map

 

 

 

Map은 key와 value쌍으로 이루어져있는 형태이다. 

TestBean3클래스에 value는 Object형으로 선언하였기 때문에 어떤 형태의 값도 다 담을 수 있을 것이다.

 

map태그 안에 entry라는 태그를 사용하여 key값과 value값을 넣어준다.

value값이 String이 아닌 기본형일때는 위와같이 value-type이라는 속성으로 선언을 해주어야 한다.

 

새로운 bean 객체를 map에 집어 넣을 때에는 k3와 같이 하면 되고,

기존에 있는 bean을 넣을 때는 k4처럼 넣으면 된다. 

 

 

 

 

 

 

 

 

 

 

 

4. Properties

 

Properties는 문자열만 담을 수 있는 컬렉션이다.

 

 

 

props 태그 아래에 prop태그를 이용하여 key값과 그 안에 들어갈 value를 설정해준다.

Properties는 문자열 밖에 담을 수 없기 때문에 뭐 따로 value속성이나 이런게 존재하지는 않는것 같다. 저런 형식으로 넣어주면 된다.

 

'JAVA > Spring' 카테고리의 다른 글

Java코드를 활용한 Bean 등록  (0) 2020.04.10
자동 주입  (0) 2020.04.10
의존성 주입 (Dependency Injection)  (0) 2020.04.09
Bean 객체의 생성시점과 생명주기  (0) 2020.04.08
IoC 컨테이너  (0) 2020.04.07

DI (Dependency Injection) 이란?

 

bean객체를 생성할 때, bean객체가 관리할 값이나 객체를 주입하는 것을 의미한다.

만약 ,객체가 생성될 때 해당 객체가 관리할 변수의 값이 정해져 있으면 알아서 bean객체가 생성될 때 변수에 값이 들어간다.

 

 

 

 

+ 2021-12-10 추가

의존하는 객체를 직접 생성하는 것이 아니라, 외부에서 생성한 후 주입하는 것.

DI를 할 때 정적인 클래스 의존관계동적인 클래스 의존관계를 생각해보아야 한다.

 

- 정적인 클래스 의존관계 ? import코드만 보고 의존관계를 파악할 수 있는 것. 애플리케이션을 실행하지 않아도 의존관계가 파악이 가능하다.

ex) public Car car = new porsche(); 

Car가 인터페이스이고 porsche가 구현 클래스라면 이 코드만 보고도 런타임 이전에 의존관계를 파악할 수 있다. 그리고 외부에서 의존관계를 주입하는 것이 아닌 직접 생성을 하고 있다.

 

 

- 동적인 클래스 의존관계 ? 런타임(실행)시점에서 의존관계를 파악할 수 있는 것.

ex) public final Car car;

Car가 인터페이스 이면 이 코드만 보고는 Car의 구현객체를 알 수 없으며 런타임 이전에 의존관계를 파악할 수가 없다. (car변수에는 생성자주입과 같은 방식으로 외부에서 주입을 받는다.)

 

 

DI를 할 때에는 코드에서는 런타임(실행)시점의 의존관계가 드러나지 않아야 한다. 즉, 동적인 클래스 의존관계여야 하며 이는 인터페이스에만 의존하고 있어야 한다는 의미와 같다. (객체지향적 설계를 위해 OCP, DIP원칙을 지키는 것과도 상통하다.)

런타임(실행)시점에서 실제 구현 객체를 생성하고 클라이언트에 주입(전달)함으로써 외부에서 의존관계를 결정해야 한다. 이와 같은 조건이 맞을 때 DI가 되었다고 한다.

 

 

 

 

 

 

 

 

 

 

 

TestBean클래스에 다음과 같이 생성자가 정의되어있다. 

기본생성자, 정수형 변수를 받는 생성자, 실수형 변수를 받는 생성자 이렇게 3개이다.

 

 

 

 

 

(printData메소드는 필드의 값을 프린트해주는 함수)

 

자바에서는 이렇게 new를 이용하여 새로운 객체를 만들어가면서 그 객체의 생성자의 매개변수에 정수형 변수, 실수형 변수를 넣으면 해당 변수의 타입에 알맞는 생성자를 찾아서 인스턴스 변수가 생성되게 된다.

 

이 작업을 spring xml에서 하려고 하면 어떻게 해야할까??

 

 

 

 

bean객체를 정의하는 bean태그안의 속성에 constructor-arg라는 태그를 추가한다.

constructor-arg태그의 속성중 value에는 생성자의 매개변수에 들어갈 변수의 value값이 들어가고 type은 매개변수의 타입이다.

 

spring에서는 String > double > int 순서로 우선순위를 가진다. 그러므로 만약 type속성을 아무것도 지정해주지 않았는데, TestBean 클래스에 String형을 매개변수로 받는 생성자가 정의되어 있다면 value값은 자동으로 String으로 인식된다.

 

최우선순위가 String이므로 만약 type이 String이면 굳이 써주지 않아도 되지만..

쓰고 싶다면, java는 String이 클래스이기 때문에 그냥 type="string" 이 아닌, type="java.lang.String" 과 같이 써주어야 하겠다.

 

 

 

 

또한 , 위와 같이 xml에 bean을 정의하는데 생성자를 통해 주입할때 생성자 매개변수의 순서는 크게 상관이 없다.

먼소리냐고?

 

 

 

 

 

 

생성자중에 다음과 같이 int, double, String 순서로 매개변수를 받는 생성자가 존재한다고 치자.

 

만약 자바에서,

 

 

이런식으로 객체를 생성했다면? 당연히 오류가 난다. 저런 매개변수를 갖는 생성자를 찾을 수 없기 때문이다.

 

그런데.. spring bean을 정의하는 xml에서는

 

 

 

이런식으로 정의한후

 

ClassPathXmlApplicationContext ctx = new CalssPathXmlApplicationContext("com/study/spring/config/bean.xml");
TestBean2 test2 = ctx.getBean("obj6", TestBean2.calss);
test2.printData();

 

이와 같이 하여도 오류가 나지 않는다는 것이다.

 

 

spring에서는 먼저, 정의된 생성자의 순서대로 값을 주입할 수 있는 생성자를 찾는다
근데 없다? 그러면 이 값을 모두 주입할 수있는 생성자를 찾는다! 

위의 예가 순서대로 값을 주입할 수 있는 생성자가 없어서 이 값을 모두 주입할 수 있는 생성자를 찾은 예가 되겠다.

 

 

 

 

 

 

 

 

객체주입

 

말로만 '객체주입' 이렇게 써놓으면 먼소린가 싶다 나도..

코드로 보자.

 

 

 

DataBean이라는 이름의 POJO class가 있다고 가정하고,

beans_data라는 이름의 bean을 정의한다. 이 bean은 prototype이니까 불러올 때마다 객체를 새로 생성한다.

 

obj7이라는 bean을 정의할때 생성자의 매개변수로서 beans_data를 2개 집어 넣는다.

대충 TestBean2가 어떻게 생겨먹었는지 유추할수 있다.

 

 

 

 

DataBean type의 매개변수 2개를 생성자에서 받는 형태는 xml에서 저렇게 정의한다.

data1과 data2는 서로 다른 변수여야 하기때문에 beans_data라는 prototype의 bean을 따로 정의해서 그 bean을 ref속성을 이용하여 집어 넣는 방법이다.

 

 

 

 

 

 

 

 

 

 

setter를 이용한 주입

 

위에 예제에서 사용된 DataBean이라는 POJO 클래스가 getter, setter가 정의되어 있다고 가정해보자.

 

 

 

 

다음과 같이 property태그를 이용하여 setter주입을 할 수 있다.

 

name이 data1이니까 setData1을 자동으로 찾아가고, value의 값을 매개변수로 자동으로 넣어준다.

property의 name 맨 앞글자를 대문자로(D) 바꾸고 앞에 set을 붙여 setData1이라는 함수를 찾는 방식으로 setter를 찾는다고 한다... (정확하진 않으나.. 강의에서 그랬음...)

 


만약 setData1이름의 메소드가 매개변수만 다르게 여러개있으면 value는 String > double > int 우선순위 순서대로 들어감

'JAVA > Spring' 카테고리의 다른 글

자동 주입  (0) 2020.04.10
컬렉션 주입  (0) 2020.04.09
Bean 객체의 생성시점과 생명주기  (0) 2020.04.08
IoC 컨테이너  (0) 2020.04.07
Maven 설정  (0) 2020.04.07

+ Recent posts