Spring. Creating main annotation to start business logic


package com.stanley.borisovSpringDeep.circularDependency;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Main {
}

a couple of classes with business logic


@Component
public class Husband {

    @Getter
    private int money;

    @Autowired
    private Wife wife;


    @Main
    public void doStuff() {
        init();
        System.out.println(String.format("got love from wife %d", wife.getLove()));
    }

    @PostConstruct
    public void init() {
        money = 1000;
    }
}

@Component
public class Wife {

    @Getter
    private int love;

    @Autowired
    private Husband husband;


    @Main
    public void doStuff() {
        init();
        System.out.println(String.format("got money from husband %d", husband.getMoney()));
    }

    @PostConstruct
    public void init() {
        love = 1000;
    }
}

ContextRefreshedEvent listener

@Component
public class MainRunnerListener {
    @Autowired
    private ConfigurableListableBeanFactory configurableListableBeanFactory;

    @SneakyThrows
    @EventListener
    public void handleListen(ContextRefreshedEvent contextRefreshedEvent) {
        var context = contextRefreshedEvent.getApplicationContext();
        var beanDefinitionIds = context.getBeanDefinitionNames();
        for (String beanDefinitionId : beanDefinitionIds) {
            var beanDefinition = configurableListableBeanFactory.getBeanDefinition(beanDefinitionId);
            var beanClassName = beanDefinition.getBeanClassName();
            if (beanClassName == null) {
                continue;
            }

            Class<?> beanClass = ClassUtils.resolveClassName(beanClassName, ClassLoader.getSystemClassLoader());
            Method[] methods = beanClass.getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(Main.class)) {
                    var bean = context.getBean(beanDefinitionId);
                    method.invoke(bean);
                }
            }
        }
    }
}

not required class

@Component
public class BeanDefinitionAppenderBeanPostProcessor implements BeanPostProcessor {
    @Autowired
    ConfigurableListableBeanFactory configurableListableBeanFactory;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Arrays.stream(configurableListableBeanFactory.getBeanDefinitionNames()).parallel().forEach(name -> {
            if (neededMainBehaviour(bean)) {
                BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(beanName);
                if (beanDefinition.getBeanClassName() == null) {
                    beanDefinition.setBeanClassName(bean.getClass().getCanonicalName());
                }
            }
        });
        return bean;
    }

    private boolean neededMainBehaviour(Object bean) {
        return Arrays.stream(bean.getClass().getMethods()).anyMatch(method -> method.isAnnotationPresent(Main.class));
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
This entry was posted in Без рубрики. Bookmark the permalink.