Spring bean 定义在运行时加载到 XmlWebApplicationContext 后出现 CGLIB 代理错误

发布于 2024-08-29 15:30:16 字数 1173 浏览 10 评论 0原文

我在运行时将其他单例 bean 定义从外部 jar 文件加载到应用程序的现有 XmlWebApplicationContext 中:


BeanFactory beanFactory = xmlWebApplicationContext.getBeanFactory();
DefaultListableBeanFactory defaultFactory = (DefaultListableBeanFactory)beanFactory;
final URL url = new URL("external.jar");
final URL[] urls = {url};
ClassLoader loader = new URLClassLoader(urls, this.getClass().getClassLoader());
defaultFactory.setBeanClassLoader(loader);
final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(defaultFactory);
final DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
resourceLoader.setClassLoader(loader);
scanner.setResourceLoader(resourceLoader);
scanner.scan("com.*");
Object bean = xmlWebApplicationContext.getBean("externalBean");


毕竟,上述 xmlWebApplicationContext 包含 bean 的所有外部定义。 但是当我尝试从上下文中获取 bean 时,会抛出异常:

无法为类生成 CGLIB 代理...

我在调试模式下看到,在 bean 初始化过程中,第一次代理是由 org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator

并尝试使用生成代理 org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

但因提到的异常而失败。

I load additional singleton beans definitions at runtime from external jar file into existing XmlWebApplicationContext of my application:


BeanFactory beanFactory = xmlWebApplicationContext.getBeanFactory();
DefaultListableBeanFactory defaultFactory = (DefaultListableBeanFactory)beanFactory;
final URL url = new URL("external.jar");
final URL[] urls = {url};
ClassLoader loader = new URLClassLoader(urls, this.getClass().getClassLoader());
defaultFactory.setBeanClassLoader(loader);
final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(defaultFactory);
final DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
resourceLoader.setClassLoader(loader);
scanner.setResourceLoader(resourceLoader);
scanner.scan("com.*");
Object bean = xmlWebApplicationContext.getBean("externalBean");


After all above xmlWebApplicationContext contains all external definitions of beans.
But when i am trying to get bean from context exception is thrown:


Couldn't generate CGLIB proxy for class ...

I saw in debug mode that in the bean initialization process first time proxy is generated by
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator

and than it is tried to generate proxy with
org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

but fails with mentioned exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静谧幽蓝 2024-09-05 15:30:16

确保 bean:

  • isn't final
  • 具有非私有构造函数

Make sure the bean:

  • isn't final
  • has a non-private constructor
当梦初醒 2024-09-05 15:30:16

原因已确定。第二个代理创建者定义是在 spring-common-manager.xml 中创建的:

"org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
which intercepts beans with names DAO, Dao, *ManagerTarget.

在我的外部 bean 创建期间,代理 bean classLoader 设置为系统类加载器。
因此代理创建者无法找到外部 bean 的类定义。

看起来,如果没有刷新类加载器,添加到默认工厂的类加载器对于某些实用程序 bean(例如代理创建者)来说是不可见的。

我的解决方案是获取代理创建者 bean 并为其隐式设置类加载器,但也许存在一些更好的方法来解决此问题。

Cause was determined. Second proxy creator definition was founded in spring-common-manager.xml:

"org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
which intercepts beans with names DAO, Dao, *ManagerTarget.

During my external bean creation, proxy bean classLoader was set to system class loader.
So proxy creator couldn't find class definition for external bean.

It seems that without refresh class loader, which added to default factory is invisible for some utility beans such proxy creators.

My Solution is to obtain proxy creator bean and to set implicitly class loader to it, but maybe some better way exists to resolve this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文