記錄

Spring) prototype을 이용한 새로운 객체 생성 본문

Web/Spring framework

Spring) prototype을 이용한 새로운 객체 생성

surhommejk 2018. 4. 30. 00:18

<기존 방식의 경우 = 싱글톤>

bean에서 객체를 가져올 때 기본적으로 싱글톤 방식으로 객체를 가져온다. 즉, 아무리 여러번 객체를 가져와도 가져올 때마다 새로 생성하는 것이 아니라 하나의 동일한 객체를 가져오게 된다는 것이다.



<scope="prototype" 의 경우 = 매번 새로운 객체 생성>

bean에서 객체를 가져올 때 기존처럼 싱글톤 방식으로 하나의 동일한 객체를 계속 가져오는 것이 아니라 getBean()으로 객체를 가져올 때마다(주입 받을 때마다) 객체를 새로 생성해서 새로운 객체를 가져오게 된다. 즉, getBean()을 통해 객체를 가져올 때(주입이 필요할 때)마다 새로운 객체가 필요하다면 scope="prototype"을 사용한다.




예제코드

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
    
    <bean id="client" class="Spring.Client" scope="prototype">
        <property name="host" value="webserver"></property>
    </bean>
</beans>


public class Client implements InitializingBean , DisposableBean {
    public Client() {
        System.out.println("Client Default");
    }
    
    private String defaulthost;
    public Client(String defaulthost){
        this.defaulthost = defaulthost;
        System.out.println("Client Overloading :" + this.defaulthost);
    }
    
    private String host;
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
        System.out.println("Client setHost() 호출 : " + this.host);
    }

    public void send(){
        System.out.println("데이터 보내기....");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Client 초기화 함수 호출");     
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Client 소멸자 함수 호출");
        
    }
}


public class MainPrototype {

    public static void main(String[] args) {
        GenericXmlApplicationContext context =
                new GenericXmlApplicationContext("classpath:ApplicationContext.xml");
        Client client = context.getBean("client", Client.class);
        Client client2 = context.getBean("client", Client.class);
        
        System.out.println("client : " + client.toString());
        System.out.println("client2 : " + client2.toString());
        //context.close();
    }
}



콘솔결과

Client Default
Client setHost() 호출 : webserver
Client 초기화 함수 호출
Client Default
Client setHost() 호출 : webserver
Client 초기화 함수 호출
client : Spring.Client@31a5c39e
client2 : Spring.Client@3f49dace


콘솔 결과의 맨 밑 두 줄을 보면 객체의 주소값이 다른 것을 확인 할 수 있다. 이는 xml에서 scope="prototype"설정을 해두었기 때문에 getBean()으로 객체를 가져올 때 기존의 싱글톤 객체를 갖는 것이 아니라 가져올 때마다 새로운 객체를 생성해서 가져왔기 때문이다.



cf) 주의할 점

@Resource나 @Autowired, 생성자 등을 이용해 의존관계 주입을 통해 직접 프로토타입 빈을 가져오려고 하면 싱글톤 빈처럼 동작해서 새로운 객체를 가져오는 것이 아니라 동일한 객체를 계속 가져오게 된다.



+ a

프로토 타입 설정과 관련하여 정리가 잘 된 포스팅을 찾았다

"주의할 점" 부분도 아래 포스팅을 참고하여 정리하였다

http://nkcnow.tistory.com/234

Comments