【重写SpringFramework】第一章beans模块:初步认识BeanFactory(chapter 1-4)

1. 前言

之前我们提到,控制反转的含义是指 IOC 容器接管了对象的创建权。举个例子,对象 A 依赖 B,但实际上 A 并不关心 B 是怎么来的,只要 IOC 容器能提供给它就行。因此在代码层面,BeanFactory 应用了简单工厂模式,屏蔽了产品的生产过程,提供给消费者的是一个可用的产品。

BeanFactory 的基本结构包括三个部分,如下图所示。首先是工厂方法,客户端调用 getBean 方法就可以获得指定的对象。其次是 Bean 的缓存,IOC 容器将自身所管理的所有 Bean 缓存起来,在整个应用程序中实现资源共享。第三,addSingleton 方法的作用是向缓存中添加一个对象。我们发现这种结构形成了一个闭环系统,有输入,有输出,还有存储。本节的目标便是实现一个最简单的 Spring 容器。

在这里插入图片描述

2. BeanFactory 体系介绍

2.1 继承结构

BeanFactory 的继承体系比较庞大,各个类和接口之间的关系也很复杂。为了让读者有一个直观的认识,下图列出了 Spring 源码中 BeanFactory 的继承结构。

在这里插入图片描述

显而易见,过于复杂的结构对于理解源码造成了很大的困难。因此,我们对原始的继承体系进行了精简,并根据功能的不同划分为三个部分。第一组是红色部分,负责单例的管理工作。

  • SingletonBeanRegistry:负责注册单例的接口
  • DefaultSingletonBeanRegistry:注册单例的实现类,用于存储 Spring 管理的单例
  • FactoryBeanRegistrySupport:用于存储 FactoryBean 类型的单例所包装的对象

第二组是蓝色部分,负责 Bean 的管理工作,实现了 BeanFactory 的核心功能。

  • BeanFactory:Spring 容器的核心接口,定义了管理 Bean 的方法
  • AutowireCapableBeanFactory:拥有自动装配的能力,也就是通常所说的依赖注入
  • ConfigurableBeanFactory:负责对 BeanFactory 进行相关配置,外界可以访问该接口
  • AbstractBeanFactory:定义了获取 Bean 的主要流程,将实际的创建工作交由子类完成
  • AbstractAutowireCapableBeanFactory:完成了 Bean 的实际创建工作,包括实例化、自动装配、初始化等功能
  • DefaultListableBeanFactory:默认的 BeanFactory 接口的实现类

第三组是黄色部分,负责 BeanDefinition 的管理工作,只有一个接口,孤悬于整个体系之外。

  • BeanDefinitionRegistry:实现了注册 BeanDefinition 的功能

在这里插入图片描述

2.2 角色分类

以上介绍了 BeanFactory 各个接口和类的基本功能,分别对 Bean、单例和 BeanDefinition 进行管理。那么这三者之间有什么联系和区别,如下所示:

  • Bean:泛指各种对象,可以由 BeanFactory 创建,也可以由外部创建。需要注意的,Spring 容器并不对所有对象进行管理。
  • 单例:一种特殊的对象,由 Spring 容器进行管理。所谓管理是指除了创建对象,还负责缓存该对象。缓存则意味着持有该项资源,这是 IOC 容器的基础。
  • BeanDefinition:定义了创建对象的细节信息,是 Spring 容器创建对象的依据。(下节介绍)

注:一个 Bean 是否能成为单例是由其作用域决定的,singleton 表示这是一个单例,而 prototype 表示该对象是原型对象,也就是说每次都创建一个新的对象,Spring 容器也不对其进行管理。我们不关心原型作用域的实现,此处仅作为单例的扩展内容加以讨论。

3. 单例管理

3.1 SingletonBeanRegistry

单例是一种特殊的 Bean,表示在应用程序中唯一存在的对象。单例由 Spring 容器进行管理,包括创建、存储、销毁等,因此也称为容器托管(managed)对象。SingletonBeanRegistry 接口定义了管理单例的相关方法,Bean 的名称唯一决定一个单例。

  • registerSingleton 方法:注册一个单例,需要指定名称。参数 singletonObject 表示一个外部创建的对象,由于对象的创建不是由 Spring 容器掌管的,因此这种注册方式很少使用。
  • getSingleton 方法:获取指定名称的单例
  • containsSingleton 方法:判断指定名称的单例是否存在
public interface SingletonBeanRegistry {
    void registerSingleton(String beanName, Object singletonObject);
    Object getSingleton(String beanName);
    boolean containsSingleton(String beanName);
}

3.2 DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistrySingletonBeanRegistry 接口的默认实现类,完成了单例的注册、查找、销毁等功能。singletonObjects 是最重要的属性,作用是存储已创建的单例。它是一个 ConcurrentHashMap 类型的对象,支持在多线程的情况下安全地进行操作。

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    //缓存单例
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    //缓存beanName
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
}

registerSingleton 方法的逻辑比较简单,首先查找缓存中是否存在实例,如果没有则将对象添加到单例缓存中。需要注意的是,方法入参 singletonObject 表示已存在的对象,是外界 new 出来的,而不是 Spring 容器创建的。因此,registerSingleton 方法只是注册单例的一种可选途径,并不是最主要的方式(仅了解)。

//注册单例
@Override
public void registerSingleton(String beanName, Object singletonObject){
    synchronized (this.singletonObjects) {
        Object obj = this.singletonObjects.get(beanName);
        if (obj != null) {
            throw new IllegalStateException("注册单例Bean失败,[" + beanName + "]已存在");
        }

        addSingleton(beanName, singletonObject);
    }
}

//将单例添加到缓存中
protected void addSingleton(String beanName, Object singletonObject) {
    this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
    this.registeredSingletons.add(beanName);
}

getSingleton 方法的作用是从缓存中查找单例,这是接口定义的方法,实际的查找工作委托给同名的重载方法。重载的 getSingleton 方法只进行了简单的处理,直接从缓存中获取实例。之后实现依赖注入的功能时,会出现循环依赖的问题,届时再会回过头来重构该方法。

//查找单例
@Override
public Object getSingleton(String beanName){
    return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    //TODO 简单实现,解决循环依赖的问题时再完善
    return this.singletonObjects.get(beanName);
}

需要注意的是,该类有三个重载的 getSingleton 方法,本节我们用到了前两个方法,简单介绍如下:

  • getSingleton(String beanName):从缓存中查找单例,这是接口定义的方法,供外界使用
  • getSingleton(String beanName, boolean allowEarlyReference):查找单例的实际逻辑,是受保护的方法,由子类调用。
  • getSingleton(String beanName, ObjectFactory<?> singletonFactory):从缓存中查找单例,如不存在则创建新对象。换句话说,Spring 容器创建对象实际上是通过该方法完成的。

3.3 FactoryBeanRegistrySupport

FactoryBeanRegistrySupport 的作用是处理 FactoryBean 类型的特殊单例,暂时不做介绍,仅作为继承体系中的一环存在。本教程的讲解原则是先介绍通用的情况,再考虑特殊的情况,否则会顾此失彼,抓不住重点。

4. Bean 的管理

4.1 BeanFactory

BeanFactory 是整个 Spring 容器的核心接口,为了简化继承结构,还将 ListableBeanFactory 接口合并进来。BeanFactory 接口定义了若干管理 Bean 的方法,根据功能将这些方法划分为三组。第一组是 getBean 系列方法,不仅可以获取实例,还包含了创建流程。第二组与 Bean 的类型有关。第三组是 ListableBeanFactory 接口的方法,特点是以枚举的方式遍历所有的 Bean,而不是像 getBean 方法一次只能获取一个实例。

public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(String name, Class<T> requiredType);
    <T> T getBean(Class<T> requiredType) throws BeansException;

    Class<?> getType(String name);
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws BeansException;
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws BeansException;

    boolean containsBeanDefinition(String beanName);
    List<String> getBeanNamesForType(Class<?> type);
    <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
}

4.2 ConfigurableBeanFactory

ConfigurableBeanFactory 接口的作用是对 Spring 容器进行一些配置工作,比如设置一些组件,或者完成某些功能。目前只列出了本节涉及到的方法,其余方法将在后续介绍。同时为了简化继承结构,将 ConfigurableListableBeanFactory 接口合并进来了。

public interface ConfigurableBeanFactory extends AutowireCapableBeanFactory, SingletonBeanRegistry {
    void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
    TypeConverter getTypeConverter();
}

4.3 AbstractBeanFactory

AbstractBeanFactory 是一个抽象类,实现了 ConfigurableBeanFactory 接口。同时还继承了 FactoryBeanRegistrySupport 类,拥有了管理单例的能力。AbstractBeanFactory 最重要的工作就是实现了一系列 getBean 方法,它们最终都调用了 doGetBean 方法。doGetBean 方法是获取 Bean 的核心方法,后续会详细分析流程,目前仅调用父类的 getSington 方法查询缓存即可。

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    //父容器
    private BeanFactory parentBeanFactory;
    //转换服务
    private ConversionService conversionService = new DefaultConversionService();
    //类型转换器
    private TypeConverter typeConverter = new SimpleTypeConverter();

    @Override
    public Object getBean(String name) throws RuntimeException {
        return doGetBean(name, null);
    }

    @Override
    public <T> T getBean(String name, Class<T> requiredType) {
        return doGetBean(name, requiredType);
    }

    //获取Bean的核心方法
    protected <T> T doGetBean(final String name, final Class<T> requiredType) {
        returnTgetSingleton(name);
    }
}

注:本节暂不介绍 AbstractAutowireCapableBeanFactoryDefaultListableBeanFactory,仅定义空的实现,用于创建 BeanFactory 实例。(代码略)

5. 测试

测试方法比较简单,首先创建 DefaultListableBeanFactory 实例,调用 registerSingleton 方法添加一个单例,且 User 对象是手动创建的。然后调用 getBean 方法获取指定名称的单例。

@Test
public void testGetBean() {
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    factory.registerSingleton("foo", new User("Foo", 18));
    Object bean = factory.getBean("foo");
    System.out.println("注册手动创建的对象: " + bean);
}

从测试结果可以看到,注册到 Spring 容器中的对象可以取出来。如果多调用几次 getBean 方法,得到的仍是同一个对象,而这正是单例的特点。

注册手动创建的对象: User{name='Foo', age=18}

6. 总结

本节初步认识了 Spring 实现的 IOC 容器,我们对 BeanFactory 的继承体系进行划分,其中 SingletonBeanRegistry 接口负责管理单例,BeanFactory 接口则是对 Bean 进行管理。两者的区别在于,Bean 泛指各种对象,而单例是一种特殊的 Bean,由 Spring 容器进行管理。

Spring 容器的基本工作包括两个方面,一是注册单例,二是获取单例。Spring 提供了两种注册单例的方式,一是通过 SingletonBeanRegistry 接口注册一个对象,这是直接的方式;二是通过 BeanDefinitionRegistry 接口注册 BeanDefinition,间接地实现对象的创建和注册。本节仅实现了第一种方式,虽然实现简单,但并不常用,因为对象的创建过程并不是由容器掌握的。

7. 项目信息

本节新增和修改内容一览,新增项(13),修改项(0)。

beans
└─ src
   ├─ main
   │  └─ java
   │     └─ cn.stimd.spring.beans
   │        └─ factory
   │           ├─ config
   │           │  ├─ AutowireCapableBeanFactory.java (+)
   │           │  ├─ ConfigurableBeanFactory.java (+)
   │           │  └─ SingletonBeanRegistry.java (+)
   │           ├─ support
   │           │  ├─ AbstractAutowireCapableBeanFactory.java (+)
   │           │  ├─ AbstractBeanFactory.java (+)
   │           │  ├─ DefaultListableBeanFactory.java (+)
   │           │  ├─ DefaultSingletonBeanRegistry.java (+)
   │           │  └─ FactoryBeanRegistrySupport.java (+)
   │           └─ BeanFactory.java (+)
   └─ test
      └─ java
         └─ beans
            └─ factory
               ├─ User.java (+)
               └─ FactoryTest.java (+)

注:+号表示新增、*表示修改
  • 项目地址:https://gitee.com/stimd/spring-wheel

  • 本节分支:https://gitee.com/stimd/spring-wheel/tree/chapter1-4

注:项目的 master 分支会跟随教程的进度不断更新,如果想查看某一节的代码,请选择对应小节的分支代码。


关注公众号【Java编程探微】,加群一起讨论。
在这里插入图片描述

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.9.jar:5.3.9] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9] 报错
最新发布
07-15
<think>首先,用户的问题是:“我想解决Spring Security启动时Bean创建失败的问题 请问Spring Security FilterChain BeanCreationException NoClassDefFoundError JAXBException 解决方案”。这是一个关于Spring Security启动错误的问题,具体错误是Bean创建失败,原因是NoClassDefFoundError: javax/xml/bind/JAXBException。 从系统级指令中,我需要: - 所有行内数学表达式使用$...$格式,但这个问题不涉及数学表达式,所以可能不需要。 - 独立公式使用$$...$$格式,但同样,这里没有数学公式。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 参考站内引用: - [^1]: 错误信息描述。 - [^2]: 详细的异常堆栈。 - [^3]: 错误原因分析。 - [^4]: 一个解决方案代码片段。 这些引用是关于Spring Security启动错误的具体信息。错误的核心是java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException,这表明缺少JAXB API类。 背景知识: - JAXB (Java Architecture for XML Binding) 是用于XML和Java对象绑定的API。 -Java 9及更高版本中,JAXB被移除了Java SE平台,因此如果项目依赖JAXB但未添加依赖,就会导致NoClassDefFoundError。 - Spring Security或相关库可能间接依赖JAXB。 解决方案: 1. **添加JAXB依赖**:在项目的构建文件中添加JAXB API的依赖。例如,在Maven中: ```xml <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> <!-- 使用最新稳定版本 --> </dependency> ``` 或者,如果是旧版本Java,使用: ```xml <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> ``` 同时,可能需要添加实现,如: ```xml <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.0</version> </dependency> ``` 2. **检查Java版本**:确保使用的Java版本兼容。如果使用Java 11或更高版本,JAXB需要显式添加。 3. **更新Spring Boot版本**:如果使用Spring Boot,更新到较新版本可能已经解决了依赖问题,因为Spring Boot管理依赖版本。 4. **参考引用[^4]**:用户提供了一个代码片段,但看起来是针对特定框架(如Ruoyi)的解决方案,可能不通用。它添加了一个NameHelper类,但这不是解决JAXB问题的直接方法。可能是一个不相关的引用。 在回答中,我需要结构化: - 解释错误原因。 - 提供逐步解决方案。 - 引用相关部分。 - 生成相关问题。 回答结构: 1. **引言**:简述问题。 2. **错误原因分析**:解释为什么会出现这个错误。 3. **解决方案**:提供具体的解决步骤。 4. **代码示例**:如果需要,给出代码。 5. **总结**。 6. **相关问题**:生成相关问题。 确保使用中文。 生成相关问题: - 例如:如何添加JAXB依赖?其他常见Spring Security错误?等。 引用处理: - 在回答中,当引用站内内容时,添加[^1]等。 - 例如,引用错误描述时。 最终回答框架: - 开头:您好,您的问题是关于Spring Security启动时Bean创建失败的错误,具体是NoClassDefFoundError: JAXBException。让我帮您一步步解决。 - 原因分析:这个错误通常是由于缺少JAXB API库引起的,因为在Java 9+中JAXB被移除了[^1]。 - 解决方案:建议添加JAXB依赖到项目中。 - 详细步骤:例如,在Maven中添加依赖。 - 代码示例:给出Maven依赖代码。 - 验证:建议重启应用检查。 - 相关问题。</think>### 解决Spring Security启动时Bean创建失败的问题 您好!您的问题是关于Spring Security启动时出现`BeanCreationException`,具体错误为`NoClassDefFoundError: javax/xml/bind/JAXBException`。这是一个常见的依赖冲突问题,通常发生在Java 9及以上版本中,因为JAXB(Java Architecture for XML Binding)API已被从Java SE标准库中移除[^1]。下面我将逐步解释原因并提供完整解决方案,确保您能顺利修复问题。 --- ### 错误原因分析 1. **核心问题**: Spring Security在初始化`springSecurityFilterChain`这个Bean时,间接依赖了JAXB API(用于XML处理)。但在Java 9+环境中,JAXB不再是JDK内置组件,导致`NoClassDefFoundError`[^2][^3]。 - 错误堆栈示例如下: ``` org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' ... nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException ``` 2. **触发场景**: - 使用Java 1117等较新JDK版本。 - Spring Boot 2.x或Spring Security 5.x项目未显式添加JAXB依赖。 - 依赖库(如Spring WS或某些XML解析器)间接引用JAXB。 3. **引用分析**: - 引用[^1][^2][^3]确认了错误细节:工厂方法`springSecurityFilterChain`因缺少JAXB类而失败。 - 引用[^4]提供了一个自定义类`NameHelper`,但这不是解决JAXB问题的直接方案(可能针对特定框架如Ruoyi),核心需添加JAXB依赖。 --- ### 解决方案(逐步操作) #### 步骤1: 添加JAXB依赖到项目 在项目的构建文件中(Maven或Gradle),显式添加JAXB API及其实现依赖。**这是最关键的修复步骤**。 - **Maven项目**(在`pom.xml`中添加): ```xml <dependencies> <!-- JAXB API(适用于Jakarta EE 9+) --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> <!-- 使用最新稳定版 --> </dependency> <!-- JAXB 运行时实现 --> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.0</version> </dependency> </dependencies> ``` 如果项目仍使用Java EE(非Jakarta),可替换为旧版: ```xml <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> ``` - **Gradle项目**(在`build.gradle`中添加): ```groovy dependencies { implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.0' } ``` #### 步骤2: 验证Java版本和依赖 - **检查JDK版本**: 运行`java -version`确认是否使用Java 9+。如果是,必须添加上述依赖。 - **清理并重建项目**: 执行Maven命令: ``` mvn clean install ``` 或Gradle命令: ``` gradle clean build ``` #### 步骤3: 更新Spring Boot版本(可选) 如果使用Spring Boot,升级到最新版本可能自动解决兼容性问题: - 在`pom.xml`中修改Spring Boot版本(推荐≥2.7.x): ```xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <!-- 或更高 --> </parent> ``` #### 步骤4: 测试启动 重启应用后,检查日志: - 成功标志:`springSecurityFilterChain` Bean正常初始化,无`JAXBException`错误。 - 失败处理: - 确保依赖无冲突:运行`mvn dependency:tree`查看是否引入多个JAXB版本。 - 排除旧依赖:如果存在冲突,在`pom.xml`中添加: ```xml <exclusions> <exclusion> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </exclusion> </exclusions> ``` --- ### 总结 通过添加JAXB依赖(如`jakarta.xml.bind-api`和`jaxb-runtime`),您可以解决`NoClassDefFoundError: JAXBException`问题,确保Spring Security正常启动[^1][^2]。此方案适用于大多数Spring Boot或纯Spring项目。如果问题仍存在,请提供完整错误日志进一步分析。 --- ### 相关问题 1. 如何检查Spring项目中的依赖冲突? 2. 在Java 17中使用Spring Security需要注意哪些兼容性问题? 3. Spring Security的`FilterChain`是如何工作的? 4. 除了JAXB,还有哪些JDK模块Java 9+中被移除并需手动添加? [^1]: 这段错误信息表示在创建名为’springSecurityFilterChain’的bean时发生了问题。这个bean是通过工厂方法在类路径资源[org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]中定义的。具体的错误原因是工厂方法’springSecurityFilterChain’抛出了异常,而该异常是由java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException引起的。 [^2]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘springSecurityFilterChain’ defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method ‘springSecurityFilterChain’ threw exception; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException [^3]: Spring security启动报错 Error creating bean with name 'springSecurityFilterChain' defined in class ...。报错详细 Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException 原因 [^4]: 增加NameHelper.java【添加到ruoyi-framework模块中com.ruoyi.framework.security.filter】 public class NameHelper { private String name; private String userType; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值