在运行时将spring bean定义加载到XmlWebApplicationContext之后的CGLIB代理错误

时间:2010-04-23 13:56:35

标签: java spring runtime cglib

我在运行时将其他单例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时抛出异常:

Couldn't generate CGLIB proxy for class ...

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

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

但未提及异常。

2 个答案:

答案 0 :(得分:0)

确保bean:

  • 不是final
  • 有一个非私人构造函数

答案 1 :(得分:0)

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

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

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

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

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