fastcampus java 온라인 강의를 들으면서 정리한 내용입니다.

Customizing the Nature of a Bean

  • Lifecycle Callbacks
  • ApplicationContextAware and BeanNameAware

LifeCycle

객체들을 관리 , 객체를 만들때(new), 객체를 없앨 때(destroy)

new라는 객체를 만들기 전

특정 빈에 대해서 자원 없앨때 close에 대한 함수

  • InitializingBean
  • DisposableBean
  • xml -init method / destroy

실행

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

ConnectionFactory connectionFactory = context.getBean("connectionFactory",ConnectionFactory.class);
log.info("result : "+connectionFactory.getConnection());
  1. Initializing Bean (Interface)

    bean이 생성 될때 미리 생성됨 : 컨테이너가 빈에 필요한 모든 속성을 설정 한 후 빈 초기화 작업을 수행

    InitializingBean 인터페이스는 afterPropertiesSet 하나의 메서드를 가진다.

    void afterPropertiesSet() throws Exception;

예제 dao.xml

<bean id="connectionFactory" class="kr.co.fastcampus.cli.ConnectionFactory" >
  <constructor-arg name="driverClass" value="org.h2.Driver"/>
  <constructor-arg name="url" value="jdbc:h2:mem:test"/>
  <constructor-arg name="user" value="sa"/>
  <constructor-arg name="password" value=""/>
</bean>

<bean id = "connection" class="java.sql.Connection"
      factory-bean = "connectionFactory"
      factory-method="createConnection"
      />

<bean id="dao" class="kr.co.fastcampus.cli.Dao">
  <constructor-arg ref="connection"></constructor-arg>
</bean>

ConnectionFactory.java

public class ConnectionFactory implements InitializingBean {
    private String driverClass;
    private String url;
    private String user;
    private String password;
    //bean을 만들지면서 Connection을 미리 생성 하기
    @Getter
    private Connection connection=null;

    public ConnectionFactory(String driverClass,String url, String user, String password) {
        this.driverClass = driverClass;
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public Connection createConnection() throws SQLException {
        try {
            Class.forName("org.h2.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String url = "jdbc:h2:mem:test;MODE=MySQL;";
        return DriverManager.getConnection(this.url,this.user,this.password);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.connection = createConnection();
    }
}
  1. Initializing Bean (xml)

    init-method 에 는 빈 팩토리를 불러올 때 실행될 메서드이름을 지정해서 사용할 수 있다.

    dao.xml

    <bean id="connectionFactory" class="kr.co.fastcampus.cli.ConnectionFactory" init-method="init" >

    ConnectionFactory.java

    public class ConnectionFactory {
        private String driverClass;
        private String url;
        private String user;
        private String password;
        //bean을 만들지면서 Connection을 미리 생성 하기
        @Getter
        private Connection connection=null;
    
        public ConnectionFactory( String driverClass,String url, String user, String password) {
            this.driverClass = driverClass;
            this.url = url;
            this.user = user;
            this.password = password;
        }
        //bean 메서드(xml)의 init의 메서드를 지정해주면 bean이 초기화될때 생성된다.
        public void init() throws Exception {
            this.connection = createConnection();
        }
    
        public Connection createConnection() throws SQLException {
            try {
                Class.forName("org.h2.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            String url = "jdbc:h2:mem:test;MODE=MySQL;";
            return DriverManager.getConnection(this.url,this.user,this.password);
        }
    }

###DisposableBean

Bean을 포함하는 컨테이너가 소멸 될 때 Bean이 콜백을 얻을 수 있습니다.

1.Disposable Bean (Interface)

DisposableBean 인터페이스는 destroy 메서드를 가진다.

void destroy() throws Exception;

ConnectionFactory.java

@Slf4j
public class ConnectionFactory implements DisposableBean {
    private String driverClass;
    private String url;
    private String user;
    private String password;
    //bean을 만들지면서 Connection을 미리 생성 하기
    @Getter
    private Connection connection=null;

    public ConnectionFactory( String driverClass,String url, String user, String password) {
        this.driverClass = driverClass;
        this.url = url;
        this.user = user;
        this.password = password;
    }
    //bean 메서드(xml)의 init의 메서드를 지정해주면 bean이 초기화될때 생성된다.
    public void init() throws Exception {
        this.connection = createConnection();
    }

    public Connection createConnection() throws SQLException {
        try {
            Class.forName("org.h2.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String url = "jdbc:h2:mem:test;MODE=MySQL;";
        return DriverManager.getConnection(this.url,this.user,this.password);
    }

    @Override
    public void destroy() throws Exception {
        log.info("destory connection");
        if(this.connection!=null){
            this.connection.close();
        }
    }
}

이렇게 해주고 위에서 getbean을 사용해서 사용했지만, 여기서는 ApplicationContext 보다 ApplicationContext클래스를 상속받고 있는 ConfigurableApplicationContext 를 사용해서 테스트를 진행해야 한다.

ConfigurableApplicationContextApplicationContext, Lifecycle, Closeable 를 상속 받고 있다.

테스트를 위한 실행

ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("dao.xml");

ConnectionFactory connectionFactory = context.getBean("connectionFactory",ConnectionFactory.class);
log.info("result : "+connectionFactory.getConnection());
context.close();

결과

00:58:37.149 [main] INFO  kr.co.fastcampus.cli.Main - result : conn0: url=jdbc:h2:mem:test user=SA
00:58:37.151 [main] INFO  k.c.fastcampus.cli.ConnectionFactory - destory connection

2.DisposableBean Bean (xml)

위의 initializing Bean을 xml 로 설정한것과 같다.destroy-method 속성을 추가 해주면 된다.

<bean id="connectionFactory" class="kr.co.fastcampus.cli.ConnectionFactory" init-method="init" destroy-method="destroy">
@Slf4j
public class ConnectionFactory {
    private String driverClass;
    private String url;
    private String user;
    private String password;
    //bean을 만들지면서 Connection을 미리 생성 하기
    @Getter
    private Connection connection=null;

    public ConnectionFactory( String driverClass,String url, String user, String password) {
        this.driverClass = driverClass;
        this.url = url;
        this.user = user;
        this.password = password;
    }
    //bean 메서드(xml)의 init의 메서드를 지정해주면 bean이 초기화될때 생성된다.
    public void init() throws Exception {
        this.connection = createConnection();
    }

    public Connection createConnection() throws SQLException {
        try {
            Class.forName("org.h2.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String url = "jdbc:h2:mem:test;MODE=MySQL;";
        return DriverManager.getConnection(this.url,this.user,this.password);
    }

    public void destroy() throws Exception {
        log.info("destory connection");
        if(this.connection!=null){
            this.connection.close();
        }
    }
}

결과는 똑같이 나온다.

01:08:23.145 [main] INFO  kr.co.fastcampus.cli.Main - result : conn0: url=jdbc:h2:mem:test user=SA
01:08:23.148 [main] INFO  k.c.fastcampus.cli.ConnectionFactory - destory connection

##Default init, destroy

default-init-method , default-destroy-method 를 beans에 추가 해주면 기본적으로 bean에서 특정 메서드로 사용이 가능하다.

<beans default-init-method="init"
       default-destroy-method="destroy"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

LifeCycle

Lifecycle 인터페이스

  • void start();

  • void stop();

  • boolean isRunning();

context가 실행 중인지 아닌지 lifeCycle의 상태를 조회 가능하다.

ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("dao.xml");
Lifecycle lifecycle = context.getBean(Lifecycle.class);
log.info("lifeCycle is Running ? "+lifecycle.isRunning());
context.close();
log.info("lifeCycle is Running ? "+lifecycle.isRunning());

결과

01:37:25.064 [main] INFO  kr.co.fastcampus.cli.Main - lifeCycle is Running ? true
01:37:25.069 [main] INFO  k.c.fastcampus.cli.ConnectionFactory - destory connection
01:37:25.070 [main] INFO  kr.co.fastcampus.cli.Main - lifeCycle is Running ? false

###ApplicationContextAware

특정 빈에서 application Context를 사용 하고 싶을때 사용

public interface ApplicationContextAware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-nature

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

Bean Scope  (0) 2020.02.11
ClassPath Scanning and Managed Components  (0) 2020.02.08
DI (Dependency Injection)  (0) 2020.02.01
Spring-Core  (0) 2020.01.19
SpringCore - IoC Container(1)  (0) 2020.01.19

+ Recent posts