Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring AOP does not propagate arguments for dynamic prototype-scoped advice #28407

Closed
ZhongGuoDragon opened this issue May 2, 2022 · 1 comment
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@ZhongGuoDragon
Copy link

ZhongGuoDragon commented May 2, 2022

If we use prototype aspect expression, and we need args type is String, but we can input other type class,the aspect method is work.

code like this:

@Aspect("perthis(execution(* com.tom.test.demo..*(..)))")
@Component
@Scope(value = "prototype")
//@Aspect("")
//@Component
////@Scope(value = "prototype")
public class AspectJ2 {
    private int num = 0;

    @Before("execution(* com.tom.test.demo..*(..)) && args(java.lang.String)")
    public <T extends String> void pointCut(JoinPoint joinPoint) {
        System.out.println("????????????????????????");
        for (int i = 0; i < joinPoint.getArgs().length; i++) {
            System.out.println(joinPoint.getArgs()[i].getClass());
            System.out.println(joinPoint.getArgs()[i]);
        }
        System.out.println("????????????????????????");
    }
}
package com.tom.test.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component()
public class Child extends Father{

    public String  setStrings(Object object) {
        return "sssss";
    }
}
Child second = (Child) context.getBean("child");
second.setStrings("abcdefg");
second.setStrings(11111111);

the console will output:

????????????????????????
class java.lang.String
abcdefg
????????????????????????
????????????????????????
class java.lang.Integer
11111111
????????????????????????

I see the code:

package org.springframework.aop.aspectj.annotation;

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
			Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

		this.declaredPointcut = declaredPointcut;
		this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
		this.methodName = aspectJAdviceMethod.getName();
		this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
		this.aspectJAdviceMethod = aspectJAdviceMethod;
		this.aspectJAdvisorFactory = aspectJAdvisorFactory;
		this.aspectInstanceFactory = aspectInstanceFactory;
		this.declarationOrder = declarationOrder;
		this.aspectName = aspectName;

		if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
			// Static part of the pointcut is a lazy type.
			Pointcut preInstantiationPointcut = Pointcuts.union(
					aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

			// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
			// If it's not a dynamic pointcut, it may be optimized out
			// by the Spring AOP infrastructure after the first evaluation.
			this.pointcut = new PerTargetInstantiationModelPointcut(
					this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
			this.lazy = true;
		}
		else {
			// A singleton aspect.
			this.pointcut = this.declaredPointcut;
			this.lazy = false;
			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
		}
	}
}

this kind AspectJ will obtain PerTargetInstantiationModelPointcut and its dynamic-match method is

boolean matches(Method method, Class<?> targetClass)

not

boolean matches(Method method, Class<?> targetClass, Object... args)

so, it lost dynamic judge, so we can pass the AspectJ with a Integer or Other args, because it only calculates static-match method, the Child.setStrings(Object object) will pass any object.

private static final class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {

		@Override
		public boolean matches(Method method, Class<?> targetClass, Object... args) {
			// you can see this.declaredPointcut.matches(method, targetClass)) is not dynamic
			return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
		}

}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label May 2, 2022
@rstoyanchev rstoyanchev added the in: core Issues in core modules (aop, beans, core, context, expression) label Feb 9, 2023
@vishalsingh2972
Copy link

@ZhongGuoDragon @rstoyanchev can you assign this to me if it's still open ?

@jhoeller jhoeller changed the title spring-projects/spring-framework Spring AOP support for prototype-scoped advice Spring AOP does not propagate arguments for dynamic prototype-scoped advice Jan 6, 2024
@jhoeller jhoeller added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 6, 2024
@jhoeller jhoeller self-assigned this Jan 6, 2024
@jhoeller jhoeller added this to the 6.1.3 milestone Jan 6, 2024
@github-actions github-actions bot added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-6.0.x labels Jan 6, 2024
jhoeller added a commit that referenced this issue Jan 6, 2024
jhoeller added a commit that referenced this issue Jan 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants