2016-03-25 3 views
2

Давайте представим, что у нас есть два Closeable бобы:Подходит ли весна? Закрытые бобы закрыты в правильном порядке?

@Component 
public class CloseableBean1 implements Closeable { 

    private BufferedOutputStream outputStream; 

    @Override 
    public void close() throws IOException { 
     try { 
      outputStream.close(); 
     } catch (Exception e) { 
      // ignore e 
     } 
    } 
} 


@Component 
public class CloseableBean2 implements Closeable {  

    @Autowired 
    private CloseableBean1 bean1; 


    @Override 
    public void close() throws IOException { 
     try { 
      bean1.close(); 
     } catch (Exception e) { 
      // ignore e 
     } 
    } 
} 

ли Spring убедитесь, что CloseableBean2 закрыт первым, а затем CloseableBean1 закрыт?

+3

Почему существует заказ на уважение? Закрытие дважды не должно приводить к исключению в соответствии с контрактом ['close'] (https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html): * Если поток уже закрыто, тогда вызов этого метода не имеет эффекта. * – Tunaki

+0

Давайте притворимся, что у вас есть компонент (например, 'Bean1'), который имеет член типа BufferedOutputStream и другой компонент, который зависит от него (например,' Bean2'). Если 'BufferOutputStream' Bean1' закрыт, а другой компонент предполагает, что он открыт и пытается писать на него, все может пойти не так (исключения выбраны и т. Д.). – Behrang

ответ

1

Там нет ничего конкретного в документации о порядке утилизации, но ... description из depends-on мы можем видеть, что depends-on следует использовать только в том случае боб явно не зависит от другого. И отмечается, что зависимый боб всегда будет уничтожен первым.

В вашем случае бобы CloseableBean2всегда будет уничтожен первым, поскольку он содержит явно зависимость от CloseableBean.


Я бы предпочел сделать дополнительную защиту. Что-то вроде:

@Component 
public class CloseableBean1 implements Closeable { 

    private boolean closed = false; 

    @Override 
    public void close() throws IOException { 
     if(closed) return; 
     outputStream.close(); 
     closed=true; 
    } 
} 

Официальная документация recommend нам:

... и внутренне отметить закрывающиеся закрытым, перед метание IOException.

Этот подход помогает избежать случайного повторного вызова close() на уже закрытом потоке. Но если при первом вызове close() произойдет исключение, мы сможем его обработать.

+0

Это похоже на то, как это работает со мной. Я запускал свое маленькое приложение несколько раз, и каждый раз, когда порядок вызовов 'close' был таким же: сначала были закрыты компоненты _parent_, а затем их соответствующие bech_child_. Не могли бы вы рассказать об этом дополнительном уровне защиты? Также вы не установили 'closed' в' true' в методе 'close()'. – Behrang

+0

Извините за неточность. Виноват. Я обновил ответ. –

Смежные вопросы