升级高版本springboot2.6.x:org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata

升级springboot高版本2.6.x

项目使用到了springcloud的oauth2依赖,直接升级springboot项目版本为最新 2.6.8(2022年6月16日)将会报以下错误: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configurationPropertiesBeans' defined in class path resource [org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.context.properties.ConfigurationPropertiesBeans] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:597) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.20.jar:5.3.20]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.context.properties.ConfigurationPropertiesBeans] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485) ~[spring-core-5.3.20.jar:5.3.20]
	at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.3.20.jar:5.3.20]
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
	at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_202]
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_202]
	at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_202]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467) ~[spring-core-5.3.20.jar:5.3.20]
	... 36 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_202]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_202]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_202]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_202]
	... 40 common frames omitted

原因

springcloud下的oauth2依赖早已停止维护,而且最新的oauth2版本不支持高版本springboot,高版本中缺少该类。我们手动创建一个即可:

package org.springframework.boot.context.properties;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lingkang
 * Created by 2022/6/16
 *
 * 此类是为了兼容高版本与springcloud低版本依赖报错问题
 * springcloud中的oauth2依赖不能使用2.4.x以上版本,但springcloud的oauth2已经停止维护了
 * 需要在 配置文件中关闭检查:spring.cloud.compatibility-verifier.enabled=false
 *
 * - Change Spring Boot version to one of the following versions [2.2.x, 2.3.x] .
 * You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn].
 * If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section.
 * If you want to disable this check, just set the property [spring.cloud.compatibility-verifier.enabled=false]
 */
public class ConfigurationBeanFactoryMetadata implements ApplicationContextAware {
    public static final String BEAN_NAME = ConfigurationBeanFactoryMetadata.class.getName();
    private ConfigurableApplicationContext applicationContext;

    public ConfigurationBeanFactoryMetadata() {
    }

    public <A extends Annotation> Map<String, Object> getBeansWithFactoryAnnotation(Class<A> type) {
        Map<String, Object> result = new HashMap();
        String[] var3 = this.applicationContext.getBeanFactory().getBeanDefinitionNames();
        int var4 = var3.length;

        for (int var5 = 0; var5 < var4; ++var5) {
            String name = var3[var5];
            if (this.findFactoryAnnotation(name, type) != null) {
                result.put(name, this.applicationContext.getBean(name));
            }
        }

        return result;
    }

    public <A extends Annotation> A findFactoryAnnotation(String beanName, Class<A> type) {
        Method method = this.findFactoryMethod(beanName);
        return method != null ? AnnotationUtils.findAnnotation(method, type) : null;
    }

    public Method findFactoryMethod(String beanName) {
        ConfigurableListableBeanFactory beanFactory = this.applicationContext.getBeanFactory();
        if (beanFactory.containsBeanDefinition(beanName)) {
            BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
            if (beanDefinition instanceof RootBeanDefinition) {
                return ((RootBeanDefinition) beanDefinition).getResolvedFactoryMethod();
            }
        }

        return null;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    }

    static void register(BeanDefinitionRegistry registry) {
        if (!registry.containsBeanDefinition(BEAN_NAME)) {
            GenericBeanDefinition definition = new GenericBeanDefinition();
            definition.setBeanClass(ConfigurationBeanFactoryMetadata.class);
            definition.setRole(2);
            registry.registerBeanDefinition(BEAN_NAME, definition);
        }

    }
}

posted @ 2022-09-16 00:08  凌康  阅读(1622)  评论(0编辑  收藏  举报