{"id":"f5577b2a69fd0e87","repo":"spring-projects/spring-framework","slug":"can-only-use-global-advisors-or-interceptors-with","errorCode":null,"errorMessage":"Can only use global advisors or interceptors with a ListableBeanFactory","messagePattern":"Can only use global advisors or interceptors with a ListableBeanFactory","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java","lineNumber":425,"sourceCode":"\t */\n\tprivate synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {\n\t\tif (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {\n\t\t\tif (this.beanFactory == null) {\n\t\t\t\tthrow new IllegalStateException(\"No BeanFactory available anymore (probably due to serialization) \" +\n\t\t\t\t\t\t\"- cannot resolve interceptor names \" + Arrays.toString(this.interceptorNames));\n\t\t\t}\n\n\t\t\t// Globals can't be last unless we specified a targetSource using the property...\n\t\t\tif (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&\n\t\t\t\t\tthis.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {\n\t\t\t\tthrow new AopConfigException(\"Target required after globals\");\n\t\t\t}\n\n\t\t\t// Materialize interceptor chain from bean names.\n\t\t\tfor (String name : this.interceptorNames) {\n\t\t\t\tif (name.endsWith(GLOBAL_SUFFIX)) {\n\t\t\t\t\tif (!(this.beanFactory instanceof ListableBeanFactory lbf)) {\n\t\t\t\t\t\tthrow new AopConfigException(\n\t\t\t\t\t\t\t\t\"Can only use global advisors or interceptors with a ListableBeanFactory\");\n\t\t\t\t\t}\n\t\t\t\t\taddGlobalAdvisors(lbf, name.substring(0, name.length() - GLOBAL_SUFFIX.length()));\n\t\t\t\t}\n\n\t\t\t\telse {\n\t\t\t\t\t// If we get here, we need to add a named interceptor.\n\t\t\t\t\t// We must check if it's a singleton or prototype.\n\t\t\t\t\tObject advice;\n\t\t\t\t\tif (this.singleton || this.beanFactory.isSingleton(name)) {\n\t\t\t\t\t\t// Add the real Advisor/Advice to the chain.\n\t\t\t\t\t\tadvice = this.beanFactory.getBean(name);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// It's a prototype Advice or Advisor: replace with a prototype.\n\t\t\t\t\t\t// Avoid unnecessary creation of prototype bean just for advisor chain initialization.\n\t\t\t\t\t\tadvice = new PrototypePlaceholderAdvisor(name);\n\t\t\t\t\t}","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java#L407-L443","documentation":"Global advisors/interceptors (entries in interceptorNames ending with '*') are resolved by enumerating beans of type Advisor/Interceptor in the BeanFactory via BeanFactoryUtils.beanNamesForTypeIncludingAncestors, which requires ListableBeanFactory. If the injected beanFactory is not listable, addGlobalAdvisors cannot run and AopConfigException is thrown.","triggerScenarios":"ProxyFactoryBean is wired with a BeanFactory that is only org.springframework.beans.factory.BeanFactory (or a minimal custom impl) rather than ListableBeanFactory, while interceptorNames contains a global '*' entry.","commonSituations":"Custom integration where ProxyFactoryBean.setBeanFactory receives a non-listable factory; embedding an AOP proxy in a non-standard container; misusing ProxyFactoryBean outside an ApplicationContext (which always provides a listable factory).","solutions":["Run the ProxyFactoryBean inside a Spring ApplicationContext so it receives a ListableBeanFactory (DefaultListableBeanFactory).","Remove the '*' global entries from interceptorNames and name advisors explicitly.","If providing a custom BeanFactory programmatically, ensure it implements ListableBeanFactory."],"exampleFix":"// before\nproxyFactoryBean.setBeanFactory(simpleBeanFactory); // not listable\nproxyFactoryBean.setInterceptorNames(new String[]{\"global*\"});\n\n// after\nproxyFactoryBean.setBeanFactory(applicationContext); // ListableBeanFactory\n// or name explicitly\nproxyFactoryBean.setInterceptorNames(new String[]{\"txAdvice\",\"secAdvice\"});","handlingStrategy":"validation","validationCode":"boolean usesGlobals = java.util.Arrays.stream(pfb.getInterceptorNames() == null ? new String[0] : pfb.getInterceptorNames())\n    .anyMatch(n -> n.endsWith(\"*\"));\nif (usesGlobals && !(beanFactory instanceof org.springframework.beans.factory.ListableBeanFactory)) {\n    throw new IllegalStateException(\"Global advisors require a ListableBeanFactory\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run ProxyFactoryBean inside an ApplicationContext so it gets a ListableBeanFactory.","Avoid global '*' entries; name advisors explicitly.","When providing a custom BeanFactory, make sure it implements ListableBeanFactory."],"tags":["aop","proxy-factory-bean","global-advisors","bean-factory"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}