How to call @PreDestroy for a bean declared with @Bean annotation

3.7k Views Asked by At

I have a bean declared with annotation @Bean

@Bean
public Set<DefaultMessageListenerContainer> beans() {
    Set<DefaultMessageListenerContainer>  containerSet = new HashSet<DefaultMessageListenerContainer>();

    return containerSet;
}

I have some operations to be performed when I am destroying the bean. How can I achieve that?

I know I can use @predestroy annotation on a method in a class annotated with @Component but not sure how can I do that when declared @Bean annotation.

EDIT :

@Bean(destroyMethod="stopContainers")
   public Set<DefaultMessageListenerContainer> containers() {
        Set<DefaultMessageListenerContainer>  containerSet = new HashSet<DefaultMessageListenerContainer>();

        return containerSet;
    }

   public void stopContainers(){
        Set<DefaultMessageListenerContainer>  containerSet = containers();
        ......
        }

    }

But I am getting an error , Couldn't find a destroy method named 'stopContainers' on bean with name 'containers' How to fix this?

2

There are 2 best solutions below

0
On

Expanded from other comment - here's an example to wrap:

@Bean(destroyMethod="stopContainers")
public StoppableSetWrapper<DefaultMessageListenerContainer> containers() {
    StoppableSetWrapper<DefaultMessageListenerContainer> wrapper = new StoppableSetWrapper<>();
    return wrapper;
}

public class StoppableSetWrapper<T> {
    private final Set<T> containers = new HashSet<T>();

    public boolean add(T container) {
        return containers.add(container);
    }

    // other Set related methods as needed...

    public void stopContainers() {
        // clean up...
    }
}

The code which uses the injected/autowired bean will need to be updated since the bean type has changed.

2
On

Generally you can specify destroyMethod parameter for the @Bean annotation. And define the particular implementation for this method in your bean class.

As you're using Set you have no chance to add destroyMethod into the Set.class. So you have to wrap it (as Andrew proposed).

Actually, I don't like this kind of approach at all. It seems more preferable not to use Set of beans and find another workaround (by destroying them one by one). In my opinion, you can implement a separate manager class performing operations on your containers.