Created
May 22, 2025 14:31
-
-
Save joshlong/779201af6211b87e26b1c2e86a52271d to your computer and use it in GitHub Desktop.
an example application that demonstrates creating a running background thread and that demonstrates selectively destroying bean definitions based on some criteria (in this case, the type of the bean)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.lifecycle; | |
import org.springframework.beans.BeansException; | |
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; | |
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |
import org.springframework.beans.factory.support.DefaultListableBeanFactory; | |
import org.springframework.boot.ApplicationArguments; | |
import org.springframework.boot.ApplicationRunner; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.boot.context.event.ApplicationReadyEvent; | |
import org.springframework.context.SmartLifecycle; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.event.EventListener; | |
import org.springframework.stereotype.Component; | |
import java.util.Map; | |
import java.util.concurrent.Executor; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
@SpringBootApplication | |
public class LifecycleApplication { | |
public static void main(String[] args) { | |
SpringApplication.run(LifecycleApplication.class, args); | |
} | |
@Bean | |
ApplicationRunner runner() { | |
return new ApplicationRunner() { | |
@Override | |
public void run(ApplicationArguments args) throws Exception { | |
System.out.println("hello short live process"); | |
} | |
}; | |
} | |
@Bean | |
ApplicationRunner farmRunner(Map<String, Animal> animals) { | |
return args -> { | |
System.out.println("there are " + animals.size() + " animals."); | |
animals.forEach((name, animal) -> System.out.println(name + " " + animal)); | |
}; | |
} | |
@Bean | |
static AnimnalBeanFactoryPostProcessor animnalBeanFactoryPostProcessor() { | |
return new AnimnalBeanFactoryPostProcessor(); | |
} | |
} | |
@Component | |
class Cat implements Animal { | |
Cat() { | |
System.out.println("meow"); | |
} | |
} | |
@Component | |
class Dog implements Animal { | |
Dog() { | |
System.out.println("woof"); | |
} | |
} | |
@Component | |
class OtherService { | |
@EventListener | |
void after(ApplicationReadyEvent readyEvent) { | |
System.out.println("after ApplicationReadyEvent"); | |
} | |
OtherService() { | |
System.out.println("OtherService"); | |
} | |
} | |
interface Animal { | |
} | |
class AnimnalBeanFactoryPostProcessor implements BeanFactoryPostProcessor { | |
@Override | |
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { | |
for (var beanName : beanFactory.getBeanDefinitionNames()) { | |
var beanDefinition = beanFactory.getBeanDefinition(beanName); | |
var type = beanFactory.getType(beanName); | |
if (type != null && Animal.class.isAssignableFrom(type)) { | |
if (beanFactory instanceof DefaultListableBeanFactory dlac) { | |
dlac.removeBeanDefinition(beanName); | |
System.out.println("deleting " + beanName + '.'); | |
} | |
} | |
// if (type != null && Animal.class.isAssignableFrom(type)) { | |
// beanDefinition.setLazyInit(true); | |
// } | |
} | |
} | |
} | |
@Component | |
class StatefulService implements SmartLifecycle, Runnable { | |
private final AtomicBoolean running = new AtomicBoolean(false); | |
private final Executor executor = Executors.newSingleThreadExecutor(); | |
@Override | |
public void start() { | |
System.out.println("start"); | |
running.set(true); | |
this.executor.execute(this); | |
} | |
@Override | |
public void stop() { | |
System.out.println("stop"); | |
running.set(false); | |
} | |
@Override | |
public boolean isRunning() { | |
return this.running.get(); | |
} | |
@Override | |
public void run() { | |
while (this.running.get()) { | |
try { | |
Thread.sleep(500); | |
} catch (InterruptedException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment