How to quickly implement the function of automatic configuration in the lower version of Spring

Needs and problems

Core demands

  • Existing system, no reconstruction

  • Spring version 3.x, do not plan to upgrade or introduce Spring Boot

  • It is expected to realize some functional enhancements on the premise of less code changes
    For example, make a unified log for the whole site, add the summary of web calls of rpg framework and the summary information of database access layer for them
    Problems faced

  • Spring of 3.x has no conditional annotation, which leads to not knowing when to configure these things and when not to configure them

  • Unable to automatically locate the auto configuration that needs to be loaded, we need other means to enable spring to load into the customized functions we put in

Core solutions

Conditional judgement

  • Judge through BeanFactoryPostProcessor
    It is an extension point provided by spring. After the definition of BeanFactory and before bean initialization, it can do some post-processing on my bean definition. At this time, it can make a judgment on my bean definition to see which bean definitions exist and which bean definitions I lack. At this time, I can also add a bean definition and add some self-defined ones Bean of righteousness
    Configuration loading
  • Writin g Java Con class
  • Introduce configuration class
    • put the written Java Con fi g class into component scan, and let the component scan of the current system contain my Con fi g
    • load my file on the path of loading through XML file, or import my file manually

Two extension points of Spring

BeanPostProcessor

  • For Bean instances
  • Provide custom logical callback after Bean creation
    After bean initialization, some processing can be done in the bean instance, and a post enhancement can be done to provide some logic
    BeanFactoryPostProcessor
  • Defined for Bean
  • Get configuration metadata before creating a Bean
  • static method needs to be defined in Java Con g (important)

Some customization of Bean

Lifecycle Callback (lifecycle)

  • InitializingBean (implement this interface) / @ PostConstruct (annotation Implementation) / init method (attribute of xml file or specified in bean annotation)
    About initialization, after the bean is created, make a customization to call a specific method after it is created successfully
  • DisposableBean / @PreDestroy / destroy-method
    DisposableBean: implement this interface. When destroying, my spring will call the corresponding method
    @PreDestroy: the annotated method will make a call when the bean is destroyed
    Destroy method: in xml, configure the method called when the bean is destroyed
    XxxAware interface
  • ApplicationContextAware
    This ApplicationContext can be injected through the interface
  • BeanFactoryAware
    You can inject this BeanFactory through the interface
  • BeanNameAware
    You can inject the bean name through the interface

Some common operations

Judge whether a class exists

  • ClassUtils.isPresent()
    Determine whether a class exists in classpath
    Determine whether a Bean is defined

  • ListableBeanFactory.containsBeanDefinition()
    Determine whether a Bean is defined

  • ListableBeanFactory.getBeanNamesForType()
    Through this method, some specific types of beans and which bean names have been defined
    Register Bean definition

  • BeanDefinitionRegistry.registerBeanDefinition()
    • GenericBeanDefinition
    Through this method, make a bean definition

  • BeanFactory.registerSingleton()
    Define a bean definition

Example

The contents are as follows:

Modification of pom file

Code:

@Configuration
public class GreetingAutoConfiguration {
    @Bean
    public static GreetingBeanFactoryPostProcessor greetingBeanFactoryPostProcessor() {//BeanFactoryPostProcessor is static
        return new GreetingBeanFactoryPostProcessor();
    }
}
@Slf4j
public class GreetingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {//After bean initialization, BeanPostProcessor does some processing in the bean instance, and can do a post enhancement to provide some logic
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        boolean hasClass = ClassUtils.isPresent("geektime.spring.hello.greeting.GreetingApplicationRunner",
                GreetingBeanFactoryPostProcessor.class.getClassLoader());//Determine whether this class exists in classpath
        if (!hasClass) {
            log.info("GreetingApplicationRunner is NOT present in CLASSPATH.");//If no output log exists
            return;
        }

        if (beanFactory.containsBeanDefinition("greetingApplicationRunner")) {//If so, judge whether the greeting application runner has been defined
            log.info("We already have a greetingApplicationRunner bean registered.");
            return;
        }

        register(beanFactory);//If it doesn't exist, we will create it ourselves to make a registration
    }

    private void register(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory instanceof BeanDefinitionRegistry) {//If the incoming beanFactory is an instance of BeanDefinitionRegistry type, you can use the registerBeanDefinition method
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();//Through this method, make a bean definition and set its class
            beanDefinition.setBeanClass(GreetingApplicationRunner.class);

            ((BeanDefinitionRegistry) beanFactory)
                    .registerBeanDefinition("greetingApplicationRunner",
                            beanDefinition);//Define the name of a bean, that is, define a bean through beanDefinition, and assign a name to it through registerBeanDefinition
        } else {
            beanFactory.registerSingleton("greetingApplicationRunner",
                    new GreetingApplicationRunner());//If it is not this class, use registerSingleton to register
        }
    }
}

Result

Automatic configuration

Manual configuration

Published 69 original articles, won praise 6, visited 1433
Private letter follow

Keywords: Spring Java xml less

Added by avatar.alex on Sat, 08 Feb 2020 12:59:53 +0200