AOP拦截器

EJB提供了拦截器功能,它可以将部分统一的业务逻辑抽象为AOP切面,可以用于日志记录、统一安全检查、参数校验等场景。这篇笔记我们介绍EJB中拦截器的使用。

@AroundInvoke 环绕拦截方法

在EJB实现类中,我们可以定义一个@AroundInvoke方法,它实现了一种环绕切面。

package com.gacfox.netstore.ejb;

import com.gacfox.netstore.api.HelloService;
import org.jboss.logging.Logger;

import javax.ejb.Stateless;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

@Stateless
public class HelloServiceImpl implements HelloService {
    private static final Logger logger = Logger.getLogger(HelloServiceImpl.class);

    @Override
    public String hello() {
        return "Hello, EJB!";
    }

    @AroundInvoke
    private Object logAroundInvoke(InvocationContext context) throws Exception {
        logger.info("invoking start");
        Object result = context.proceed();
        logger.info("invoking end");
        return result;
    }
}

代码中,logAroundInvoke()是一个环绕切面方法,它的方法签名是固定的,方法体中,我们在被拦截的代码逻辑执行前和执行后打印了日志信息。当hello()方法被调用时,这个环绕切面就会起作用,在hello()的执行前后插入环绕切面逻辑。InvocationContext对象包含了方法调用相关的信息,我们可以从其中获取传入的方法名、参数等。

使用拦截器类

前面我们在一个EJB实现类内部使用了@AroundInvoke环绕拦截方法,它只能作用于一个EJB内,我们还可以定义单独的拦截器并配置到多个EJB上,这样的拦截器更具通用性,下面是一个例子。

package com.gacfox.netstore.ejb;

import org.jboss.logging.Logger;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class LogInterceptor {
    private static final Logger logger = Logger.getLogger(LogInterceptor.class);

    @AroundInvoke
    public Object logAroundInvoke(InvocationContext context) throws Exception {
        logger.info("invoking start");
        Object result = context.proceed();
        logger.info("invoking end");
        return result;
    }
}
package com.gacfox.netstore.ejb;

import com.gacfox.netstore.api.HelloService;
import org.jboss.logging.Logger;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Interceptors(LogInterceptor.class)
public class HelloServiceImpl implements HelloService {
    private static final Logger logger = Logger.getLogger(HelloServiceImpl.class);

    @Override
    public String hello() {
        return "Hello, EJB!";
    }
}

在EJB实现了类上我们使用了@Interceptors注解,这个注解表示将拦截器类应用到该EJB上,它可以标注在类上也可以标注在方法上,前者拦截器对类的所有方法起效,后者拦截器只对标注的方法起效。此外,我们也可以标注多个拦截器,通过InvocationContext多个拦截器之间可以传递数据,形成链式处理逻辑。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap