You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring AOP中创建id为proxy的Bean报错,请求排查解决

问题描述

我基于Spring 3.0实现了一套AOP代码,包含以下文件:

applicatonContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
                   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="obj" class="com.learningspring.aop.aopA"/>
    <bean id="beforeAdvisor" class="com.learningspring.aop.BeforeAdvisor"/>
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="obj"/>
        <property name="interceptorNames">
            <list>
                <value>beforeAdvisor</value>
            </list>
        </property>
    </bean>
</beans>

aopA.java

package com.learningspring.aop;
public class aopA {
    public void m() {
        System.out.println("Actual business logic");
    }
}

BeforeAdvisor.java

package com.learningspring.aop;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAdvisor implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
             System.out.println("Additional concern before actual logic ");
    }
}

TestAOP.java

package com.learningspring.aop;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;  

public class TestAOP {
    public static void main(String[] args) {
        Resource r = new ClassPathResource("applicationContext.xml");
        BeanFactory bf = new XmlBeanFactory(r);
        aopA a = (aopA) bf.getBean("proxy");
        a.m();
    }
}

运行测试类时,出现创建proxy Bean失败的错误,错误信息如下:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'proxy': FactoryBean threw exception on object creation; nested exception is java.lang.ExceptionInInitializerError
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:150)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1387)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
    at com.learningspring.aop.TestAOP.main(TestAOP.java:19)
Caused by: java.lang.ExceptionInInitializerError
    at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:166)
    at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:116)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
    at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
    at org.springframework.aop.framework.Cglib2AopProxy.createEnhancer(Cglib2AopProxy.java:228)
    at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:170)
    at org.springframework.aop.framework.ProxyFactoryBean.getProxy(ProxyFactoryBean.java:362)
    at org.springframework.aop.framework.ProxyFactoryBean.getSingletonInstance(ProxyFactoryBean.java:316)
    at org.springframework.aop.framework.ProxyFactoryBean.getObject(ProxyFactoryBean.java:242)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:143)
    ... 5 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @445b295b
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
    at net.sf.cglib.core.ReflectUtils$2.run(ReflectUtils.java:56)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
    at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:46)
    ... 19 more
问题分析

这个错误的核心原因是Spring 3.0依赖的旧版本CGLIB(net.sf.cglib)与Java 9及以上版本的模块系统(JPMS)不兼容。

Java 9引入了模块访问控制机制,限制了对JDK内部API的反射访问。而旧版CGLIB需要通过反射调用ClassLoader.defineClass()方法来生成代理类,这个操作在Java 9+中被模块系统拦截,导致CGLIB初始化失败,最终引发ExceptionInInitializerError。

另外,Spring 3.0是2010年发布的版本,官方仅支持Java 5到Java 8,本身就没有适配Java 9+的模块系统。

解决方案

提供三种可行的解决方式,按推荐优先级排序:

1. 降级Java版本到Java 8及以下

这是最直接的解决方案,因为Spring 3.0原本设计就兼容Java 8及更早版本。切换到Java 8运行代码,模块系统的限制不会生效,CGLIB可以正常生成代理类,代码无需修改。

2. 在Java 9+中添加JVM启动参数开放访问权限

如果必须使用Java 9+,可以通过添加JVM参数,允许未命名模块(CGLIB所在的模块)访问java.lang包的内部API:

--add-opens java.base/java.lang=ALL-UNNAMED
  • 直接运行java命令时:在启动命令末尾加上该参数,比如:
    java --add-opens java.base/java.lang=ALL-UNNAMED com.learningspring.aop.TestAOP
    
  • 使用Maven运行测试时:在pom.xml的maven-surefire-plugin中配置参数:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M7</version>
        <configuration>
            <argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
        </configuration>
    </plugin>
    

3. 升级Spring版本到支持Java 9+的版本

推荐长期解决方案是升级到Spring 5.0及以上版本(Spring 5最低支持Java 8,兼容Java 9+)。新版本Spring已经替换了旧的net.sf.cglib,改用适配JPMS的org.springframework.cglib(基于CGLIB 3.3+),同时也淘汰了过时的XmlBeanFactory。

修改后的TestAOP.java(Spring 5版本)

package com.learningspring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAOP {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        aopA a = context.getBean("proxy", aopA.class);
        a.m();
    }
}

同时需要更新Spring依赖(以Maven为例),替换Spring 3.0的依赖为Spring 5.x版本:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.29</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.3.29</version>
    </dependency>
</dependencies>

内容的提问来源于stack exchange,提问作者Arun Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:35:24