参考自:http://stackoverflow.com/questions/33024977/pass-method-argument-in-aspect-of-custom-annotation
经过梳理做成的DEMO,附件有完整示例。
package org.demo.el; import org.demo.el.interceptor.CheckEntity; public class Company { private Long id; private String name; private Employee managingDirector; public String getName() { return name; } @CheckEntity(key = "#name") public void setName(String name) { this.name = name; } public Employee getManagingDirector() { return managingDirector; } public void setManagingDirector(Employee managingDirector) { this.managingDirector = managingDirector; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
package org.demo.el.interceptor; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CheckEntity { String message() default "Check entity msg"; String key() default "#id"; }
package org.demo.el.interceptor; import java.lang.reflect.Method; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.expression.AnnotatedElementKey; import org.springframework.expression.EvaluationContext; import org.springframework.stereotype.Component; /** * http://stackoverflow.com/questions/33024977/pass-method-argument-in-aspect-of-custom-annotation * * */ @Component @Aspect public class CheckEntityAspect { protected final Log logger = LogFactory.getLog(getClass()); private ExpressionEvaluator<Long> evaluator = new ExpressionEvaluator<>(); @Before("execution(* *.*(..)) && @annotation(checkEntity)") public void checkEntity(JoinPoint joinPoint, CheckEntity checkEntity) { Long result = getValue(joinPoint, checkEntity.key()); logger.info("result: " + result); System.out.println("running entity check: " + joinPoint.getSignature().getName()); } private Long getValue(JoinPoint joinPoint, String condition) { return getValue(joinPoint.getTarget(), joinPoint.getArgs(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), condition); } private Long getValue(Object object, Object[] args, Class clazz, Method method, String condition) { if (args == null) { return null; } EvaluationContext evaluationContext = evaluator.createEvaluationContext(object, clazz, method, args); AnnotatedElementKey methodKey = new AnnotatedElementKey(method, clazz); return evaluator.condition(condition, methodKey, evaluationContext, Long.class); } }
package org.demo.el.interceptor; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.aop.support.AopUtils; import org.springframework.context.expression.AnnotatedElementKey; import org.springframework.context.expression.CachedExpressionEvaluator; import org.springframework.context.expression.MethodBasedEvaluationContext; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; public class ExpressionEvaluator<T> extends CachedExpressionEvaluator { // shared param discoverer since it caches data internally private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer(); private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<>(64); private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64); /** * Create the suitable {@link EvaluationContext} for the specified event handling on the * specified method. */ public EvaluationContext createEvaluationContext(Object object, Class<?> targetClass, Method method, Object[] args) { Method targetMethod = getTargetMethod(targetClass, method); ExpressionRootObject root = new ExpressionRootObject(object, args); return new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer); } /** * Specify if the condition defined by the specified expression matches. */ public T condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) { return getExpression(this.conditionCache, elementKey, conditionExpression) .getValue(evalContext, clazz); } private Method getTargetMethod(Class<?> targetClass, Method method) { AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass); Method targetMethod = this.targetMethodCache.get(methodKey); if (targetMethod == null) { targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); if (targetMethod == null) { targetMethod = method; } this.targetMethodCache.put(methodKey, targetMethod); } return targetMethod; } }
package org.demo.el.interceptor; public class ExpressionRootObject { private final Object object; private final Object[] args; public ExpressionRootObject(Object object, Object[] args) { this.object = object; this.args = args; } public Object getObject() { return object; } public Object[] getArgs() { return args; } }
package org.demo; /** * */ import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; // @ActiveProfiles({"product"}) @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestApp.class) public abstract class AbsTestCase { }
/** * */ package org.demo; import org.demo.el.Company; import org.demo.el.interceptor.CheckEntity; import org.springframework.stereotype.Service; @Service public class Service1 { @CheckEntity(key = "#compay.id") public void serviceMethod1(String name, Long id, Company compay) { System.err.println("id: " + id + " ,name: " + name); } }
package org.demo; import javax.annotation.Resource; import org.demo.el.Company; import org.junit.Test; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @EnableWebMvc public class SpringTester extends AbsTestCase { @Resource private Service1 service1; /** * @throws Exception */ @Test public void test1() throws Exception { Company company = new Company(); company.setId(121L); company.setName("company name1"); service1.serviceMethod1("name1", 1L, company); System.err.println("test1()"); } }
package org.demo; /** * */ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class}) @ComponentScan(basePackages = {"org.demo"}) @EnableAspectJAutoProxy @SpringBootApplication public class TestApp { /** * @param args */ public static void main(String[] args) { } }
扫描二维码关注公众号,回复:
522846 查看本文章