{"id":"24b85361eeee5533","repo":"spring-projects/spring-framework","slug":"target-required-after-globals","errorCode":null,"errorMessage":"Target required after globals","messagePattern":"Target required after globals","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java","lineNumber":418,"sourceCode":"\t}\n\n\t/**\n\t * Create the advisor (interceptor) chain. Advisors that are sourced\n\t * from a BeanFactory will be refreshed each time a new prototype instance\n\t * is added. Interceptors added programmatically through the factory API\n\t * are unaffected by such changes.\n\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.","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java#L400-L436","documentation":"In initializeAdvisorChain(), if the last entry of interceptorNames is a global advisor (ends with '*') and no target was supplied (targetName==null and targetSource is empty), Spring cannot build the proxy because globals only contribute advice - the proxy still needs a target. Hence 'Target required after globals'.","triggerScenarios":"Configuring interceptorNames ending with a global pattern (e.g. 'global*' or 'foo*') without also providing a target, targetName, or a non-empty targetSource on the ProxyFactoryBean.","commonSituations":"XML config that relies on global advisors but forgets to wire the target bean; using the legacy global-advisor convention without a concluding target entry.","solutions":["Set target / targetName / targetSource on the ProxyFactoryBean, OR","Add the target bean name as the final (non-global) entry of interceptorNames, OR","Drop the global suffix from interceptorNames and reference advisors explicitly."],"exampleFix":"// before\n<property name=\"interceptorNames\" value=\"global*\"/>\n\n// after\n<property name=\"interceptorNames\" value=\"global*\"/>\n<property name=\"targetName\" value=\"myService\"/>","handlingStrategy":"validation","validationCode":"String[] names = pfb.getInterceptorNames();\nboolean endsWithGlobal = names != null && names.length > 0 && names[names.length - 1].endsWith(\"*\");\nboolean hasTarget = pfb.getTargetName() != null || pfb.getTargetSource() != null;\nif (endsWithGlobal && !hasTarget) {\n    throw new IllegalStateException(\"Global-only interceptorNames require an explicit target on ProxyFactoryBean\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair global '*' entries with an explicit target/targetName.","Avoid relying on global advisors as the sole chain member.","Prefer naming advisors explicitly to make the chain deterministic."],"tags":["aop","proxy-factory-bean","global-advisors","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}