{"record":{"id":"cf4c9c449e0005a0","repo":"spring-projects/spring-framework","slug":"bean-with-name-beanname-is-a-singleton-but-as","errorCode":null,"errorMessage":"Bean with name '{beanName}' is a singleton, but aspect instantiation model is not singleton","messagePattern":"Bean with name '(.+?)' is a singleton, but aspect instantiation model is not singleton","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectJAdvisorsBuilder.java","lineNumber":126,"sourceCode":"\t\t\t\t\t\tif (this.advisorFactory.isAspect(beanType)) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tAspectMetadata amd = new AspectMetadata(beanType, beanName);\n\t\t\t\t\t\t\t\tif (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {\n\t\t\t\t\t\t\t\t\tMetadataAwareAspectInstanceFactory factory =\n\t\t\t\t\t\t\t\t\t\t\tnew BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);\n\t\t\t\t\t\t\t\t\tList<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);\n\t\t\t\t\t\t\t\t\tif (this.beanFactory.isSingleton(beanName)) {\n\t\t\t\t\t\t\t\t\t\tthis.advisorsCache.put(beanName, classAdvisors);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\tthis.aspectFactoryCache.put(beanName, factory);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tadvisors.addAll(classAdvisors);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t// Per target or per this.\n\t\t\t\t\t\t\t\t\tif (this.beanFactory.isSingleton(beanName)) {\n\t\t\t\t\t\t\t\t\t\tthrow new IllegalArgumentException(\"Bean with name '\" + beanName +\n\t\t\t\t\t\t\t\t\t\t\t\t\"' is a singleton, but aspect instantiation model is not singleton\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tMetadataAwareAspectInstanceFactory factory =\n\t\t\t\t\t\t\t\t\t\t\tnew PrototypeAspectInstanceFactory(this.beanFactory, beanName);\n\t\t\t\t\t\t\t\t\tthis.aspectFactoryCache.put(beanName, factory);\n\t\t\t\t\t\t\t\t\tadvisors.addAll(this.advisorFactory.getAdvisors(factory));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\taspectNames.add(beanName);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch (IllegalArgumentException | IllegalStateException | AopConfigException ex) {\n\t\t\t\t\t\t\t\tif (logger.isDebugEnabled()) {\n\t\t\t\t\t\t\t\t\tlogger.debug(\"Ignoring incompatible aspect [\" + beanType.getName() + \"]: \" + ex);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.aspectBeanNames = aspectNames;\n\t\t\t\t\treturn advisors;","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectJAdvisorsBuilder.java#L108-L144","documentation":"Thrown as an IllegalArgumentException from BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() when an aspect bean declares a non-singleton per-clause (perthis/pertarget/pertypewithin) but the bean itself is registered as a singleton in the BeanFactory. The two are contradictory: a per-object aspect must produce a new instance per target, which a singleton-scoped bean cannot do. Spring catches this mismatch before attempting prototype-based instantiation.","triggerScenarios":"Declaring a bean annotated @Aspect(\"perthis(...)\") or @Aspect(\"pertarget(...)\") without setting @Scope(\"prototype\"); XML bean declaration with singleton='true' (the default) whose class is a perthis/pertarget aspect; a @Configuration @Bean method returning a non-singleton aspect without specifying prototype scope.","commonSituations":"Forgetting to add @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) on a perthis/pertarget aspect; copy-pasting an aspect that worked under native AspectJ (where Spring scope is irrelevant) into a Spring AOP auto-proxy context.","solutions":["Annotate the aspect bean with @Scope(\"prototype\") so each advised target gets its own instance.","Alternatively, change the aspect per-clause to singleton if per-object state is unnecessary.","In XML, set scope=\"prototype\" on the aspect bean definition."],"exampleFix":"// before\n@Aspect(\"pertarget(execution(* com.example.Target.*(..)))\")\n@Component\npublic class PerTargetAspect { ... } // singleton by default -> throws\n// after\nimport org.springframework.context.annotation.Scope;\n\n@Aspect(\"pertarget(execution(* com.example.Target.*(..)))\")\n@Component\n@Scope(\"prototype\")\npublic class PerTargetAspect { ... }","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.reflect.AjTypeSystem;\nimport org.aspectj.lang.reflect.PerClauseKind;\nimport org.springframework.beans.factory.config.ConfigurableBeanFactory;\n\npublic static String requiredScope(Class<?> aspectClass) {\n    var kind = AjTypeSystem.getAjType(aspectClass).getPerClause().getKind();\n    return (kind == PerClauseKind.SINGLETON)\n        ? ConfigurableBeanFactory.SCOPE_SINGLETON\n        : ConfigurableBeanFactory.SCOPE_PROTOTYPE;\n}\n\n// for a perthis/pertarget aspect bean, ensure scope is prototype before context refresh.\n","typeGuard":"import org.aspectj.lang.reflect.AjTypeSystem;\nimport org.aspectj.lang.reflect.PerClauseKind;\n\npublic static boolean needsPrototypeScope(Class<?> aspectClass) {\n    var k = AjTypeSystem.getAjType(aspectClass).getPerClause().getKind();\n    return k == PerClauseKind.PERTHIS || k == PerClauseKind.PERTARGET || k == PerClauseKind.PERTYPEWITHIN;\n}","tryCatchPattern":"// BeanFactoryAspectJAdvisorsBuilder catches IllegalArgumentException/IllegalStateException/AopConfigException\n// itself and logs at debug; raise logging to DEBUG to surface such incompatible aspects.\n// Otherwise validate bean scopes up front (see validationCode).","preventionTips":["Always pair @Aspect(\"perthis(...)\") / pertarget / pertypewithin with @Scope(\"prototype\").","Add a BeanFactoryPostProcessor that checks aspect beans' scopes match their per-clause.","In XML, set scope=\"prototype\" on per-object aspect beans."],"tags":["spring-aop","aspectj","bean-scope","instantiation-model","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}