参考自: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) { } }
相关推荐
此外,在获取方法返回值时,我们还可以使用 Spring 的 AOP 机制来拦截方法调用。在下面的配置文件中,我们使用 AOP 机制来拦截 JFrame 对象的 add 方法: ``` <aop:config> <aop:aspect id="myAspect" ref=...
1. **注解处理器**:创建一个自定义注解处理器,通常是一个Spring的`@Aspect`组件,它会在方法执行前进行拦截,调用权限服务进行权限验证。 2. **标签库**:定义自定义标签,与Spring的EL表达式结合,获取当前用户...
本篇将详细介绍如何在Spring MVC中自定义实现防重复提交机制,特别是通过使用“token”标签的方式。 首先,理解防重复提交的核心原理:在客户端请求时生成一个唯一的标识(token),并将这个标识存储在服务器端和...
Spring Security和Spring Framework是Java开发中的两个核心组件,它们在构建安全、可扩展的企业级应用程序中扮演着重要角色。这两个库都是Spring生态系统的一部分,由Pivotal Software公司维护。 Spring Framework...
3. **表达式语言**:在3.0.5中,Spring Security引入了Spring EL(Expression Language)来增强访问控制表达式,允许在访问控制规则中使用更复杂的条件判断,比如`hasRole('ROLE_ADMIN')`或`@Secured('IS_...
4. **spring-aop**:此模块实现了面向切面编程,允许在不修改源代码的情况下,对方法进行拦截和增强。这常用于日志记录、事务管理、性能监控等场景。 5. **spring-aspects**:提供了与AspectJ集成的能力,增强了...
在这个Java Web开发教程的后续章节中,涵盖了更多的话题,如Servlet、AJAX、自定义MVC框架、Spring的IOC和AOP、Spring MVC的原理和搭建、Spring MVC的核心对象和拦截器、自定义ORM框架、MyBatis框架的使用和高级应用...
Spring AOP通过代理模式实现,可以是JDK动态代理或CGLIB代理,用于拦截方法调用并在执行前后插入自定义的行为。 接下来,我们来看AspectJ的引入。AspectJ是一种完全的AOP语言,拥有更丰富的语法和更强的功能,如...
Spring AOP通过拦截技术实现了这一功能。 **1.2 AOP概念** AOP的主要概念包括: - **切面**:封装了横切关注点的行为。 - **连接点**:应用程序执行过程中某个特定位置。 - **通知**:在特定连接点执行的代码块。 ...
4. **@PathVariable注解**:在处理RESTful风格的URL时,@PathVariable可以从URL路径变量中获取值。例如,`@PathVariable("id") Long id`可以从URL路径如`/users/{id}`中提取"id"。 5. **HandlerAdapter和...
- **spring-aop.jar**:实现了AOP框架,允许定义方法拦截器和切面,为对象提供非侵入式的行为。 - **spring-expression.jar (Spring EL)**:Spring表达式语言,用于在运行时查询和操作对象图。 2. **日志包:...
在Spring Security中,**AOP(面向切面编程)**扮演着重要角色。它允许我们在不修改源代码的情况下,对方法执行前后的行为进行增强,比如添加安全检查。Spring Security利用AOP实现全局的安全控制,例如,可以定义一...
在IT行业中,SSH(Spring、Struts2、Hibernate)是一个常见的Java Web开发框架组合,用于构建高效、可维护的企业级应用程序。在这个项目中,“spring+struts2+hibernate整合实现分页”是一个基础教程,旨在帮助初学...
10. **SpEL在AOP中的应用**:在Spring AOP中,SpEL常用于定义切入点表达式,允许基于方法参数、返回值甚至执行时的上下文来决定拦截哪些方法。 在Spring 3.0.2 API文档中,你可以找到关于SpEL的详细说明,包括每个...
使用EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)标签来获取和展示数据。 10. **测试运行**:配置好Web应用的部署目录,启动Tomcat服务器,通过浏览器访问应用,测试增删改查功能...
6. **编写视图**:在JSP页面中使用EL(Expression Language)和JSTL标签来展示模型数据。 在实际应用中,我们还会涉及到一些高级特性和最佳实践,例如: - **AOP(面向切面编程)**:可以用来实现事务管理、日志...
4. **AOP集成**:Spring的AOP可以在JSF的bean中实现拦截器,用于执行如日志记录、性能监控等操作。 5. **数据绑定和验证**:JSF的EL(Expression Language)可以与Spring的bean进行数据绑定,同时,Spring的...
3. **在Action中使用消息**:通过调用`getText`方法来获取对应的语言资源。 4. **在视图中使用消息**:使用JSTL标签或EL表达式来显示国际化的文本。 ##### 12.3.4 基于POJO的Action开发 Struts2允许使用POJO作为...