`
conkeyn
  • 浏览: 1529392 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

在自定义spring aop中使用el获取拦截方法的变量值。

 
阅读更多

参考自: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实战之获取方法返回值操作示例

    此外,在获取方法返回值时,我们还可以使用 Spring 的 AOP 机制来拦截方法调用。在下面的配置文件中,我们使用 AOP 机制来拦截 JFrame 对象的 add 方法: ``` &lt;aop:config&gt; &lt;aop:aspect id="myAspect" ref=...

    ssm+自定义标签+自定义注解 实现权限细粒度控制

    1. **注解处理器**:创建一个自定义注解处理器,通常是一个Spring的`@Aspect`组件,它会在方法执行前进行拦截,调用权限服务进行权限验证。 2. **标签库**:定义自定义标签,与Spring的EL表达式结合,获取当前用户...

    springMVC自定义防重复提交

    本篇将详细介绍如何在Spring MVC中自定义实现防重复提交机制,特别是通过使用“token”标签的方式。 首先,理解防重复提交的核心原理:在客户端请求时生成一个唯一的标识(token),并将这个标识存储在服务器端和...

    spring-security-3.2.9和spring-framework-3.2.4的jar包和源码

    Spring Security和Spring Framework是Java开发中的两个核心组件,它们在构建安全、可扩展的企业级应用程序中扮演着重要角色。这两个库都是Spring生态系统的一部分,由Pivotal Software公司维护。 Spring Framework...

    spring-security-3.0.5.RELEASE

    3. **表达式语言**:在3.0.5中,Spring Security引入了Spring EL(Expression Language)来增强访问控制表达式,允许在访问控制规则中使用更复杂的条件判断,比如`hasRole('ROLE_ADMIN')`或`@Secured('IS_...

    spring应用必须的类库

    4. **spring-aop**:此模块实现了面向切面编程,允许在不修改源代码的情况下,对方法进行拦截和增强。这常用于日志记录、事务管理、性能监控等场景。 5. **spring-aspects**:提供了与AspectJ集成的能力,增强了...

    完整版Java web开发教程PPT课件 Java开发进阶教程 第09章 jstl、EL、Bean(共18页).pptx

    在这个Java Web开发教程的后续章节中,涵盖了更多的话题,如Servlet、AJAX、自定义MVC框架、Spring的IOC和AOP、Spring MVC的原理和搭建、Spring MVC的核心对象和拦截器、自定义ORM框架、MyBatis框架的使用和高级应用...

    spring-aspectj-ltw-xml-based-demo

    Spring AOP通过代理模式实现,可以是JDK动态代理或CGLIB代理,用于拦截方法调用并在执行前后插入自定义的行为。 接下来,我们来看AspectJ的引入。AspectJ是一种完全的AOP语言,拥有更丰富的语法和更强的功能,如...

    Spring教程

    Spring AOP通过拦截技术实现了这一功能。 **1.2 AOP概念** AOP的主要概念包括: - **切面**:封装了横切关注点的行为。 - **连接点**:应用程序执行过程中某个特定位置。 - **通知**:在特定连接点执行的代码块。 ...

    org.springframework.web.servlet-3.1.0.RELEASE.jar.zip

    4. **@PathVariable注解**:在处理RESTful风格的URL时,@PathVariable可以从URL路径变量中获取值。例如,`@PathVariable("id") Long id`可以从URL路径如`/users/{id}`中提取"id"。 5. **HandlerAdapter和...

    spring需要的jar包

    - **spring-aop.jar**:实现了AOP框架,允许定义方法拦截器和切面,为对象提供非侵入式的行为。 - **spring-expression.jar (Spring EL)**:Spring表达式语言,用于在运行时查询和操作对象图。 2. **日志包:...

    spring security教程

    在Spring Security中,**AOP(面向切面编程)**扮演着重要角色。它允许我们在不修改源代码的情况下,对方法执行前后的行为进行增强,比如添加安全检查。Spring Security利用AOP实现全局的安全控制,例如,可以定义一...

    spring+struts2+hibernate整合实现分页

    在IT行业中,SSH(Spring、Struts2、Hibernate)是一个常见的Java Web开发框架组合,用于构建高效、可维护的企业级应用程序。在这个项目中,“spring+struts2+hibernate整合实现分页”是一个基础教程,旨在帮助初学...

    spring3.0.2api 文档spring表达式语言

    10. **SpEL在AOP中的应用**:在Spring AOP中,SpEL常用于定义切入点表达式,允许基于方法参数、返回值甚至执行时的上下文来决定拦截哪些方法。 在Spring 3.0.2 API文档中,你可以找到关于SpEL的详细说明,包括每个...

    springmvc整合mybatis加jsp实现简单的增删改查

    使用EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)标签来获取和展示数据。 10. **测试运行**:配置好Web应用的部署目录,启动Tomcat服务器,通过浏览器访问应用,测试增删改查功能...

    spring mvc step by step,例子

    6. **编写视图**:在JSP页面中使用EL(Expression Language)和JSTL标签来展示模型数据。 在实际应用中,我们还会涉及到一些高级特性和最佳实践,例如: - **AOP(面向切面编程)**:可以用来实现事务管理、日志...

    jsf+spring整合

    4. **AOP集成**:Spring的AOP可以在JSF的bean中实现拦截器,用于执行如日志记录、性能监控等操作。 5. **数据绑定和验证**:JSF的EL(Expression Language)可以与Spring的bean进行数据绑定,同时,Spring的...

    开发struts2+spring

    3. **在Action中使用消息**:通过调用`getText`方法来获取对应的语言资源。 4. **在视图中使用消息**:使用JSTL标签或EL表达式来显示国际化的文本。 ##### 12.3.4 基于POJO的Action开发 Struts2允许使用POJO作为...

Global site tag (gtag.js) - Google Analytics