一个简单的例子实现自己的AOP

AOP是Aspect Oriented Programming的缩写,意思是面向切面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种编程思想。

从OOP角度分析,我们关注业务的处理逻辑,是属于纵向的行为,从AOP角度分析,我们关注对象行为发生时的问题,是属于横向的行为。

AOP 作用:

1 监控函数的调用

2 捕获异常发生

实际应用在:事务、安全、日志等横切关注。

下面是aop打印service层的方法日志为例:

/**
 * @功能描述: Service层日志/异常切面类
 */
@Component
@Aspect
public class ApiServiceAspect {

    private final Logger logger = Logger.getLogger(this.getClass());

    /**
     * 切面
     */
    private final String POINT_CUT = 
        "execution(* com.demo.bigdata.service.*.*.*(..))";

    @Pointcut(POINT_CUT)
    private void pointcut(){}

    @Before(value = POINT_CUT)
    public void before(JoinPoint joinPoint) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        StringBuilder log = new StringBuilder();
        log.append("before: ")
                .append(className)
                .append("@")
                .append(methodName)
                .append(" , params: ");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            log.append(JSONObject.toJSONString(arg) + ", ");
        }
        logger.info(log.toString());
    }

    @AfterReturning(value = "pointcut()", returning = "returnObj")
    public void afterReturn(Object returnObj) {
        String result = JSONObject.toJSONString(returnObj);
        logger.info("afterReturning: "+result);
    }

    @AfterThrowing(value = POINT_CUT, throwing = "e")
    public void afterThrowing(Throwable e) {
        logger.error("afterThrowing: "+e.getMessage(), e);
    }

    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) 
        throws Throwable {
        Long begin = System.currentTimeMillis();
        StringBuilder log = new StringBuilder("around: ");
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Exception e) {
            logger.error(log + e.getMessage(), e);
        }
        Long end = System.currentTimeMillis();
        log.append(" 执行时间: ")
                .append(end-begin)
                .append("ms");
        return result;
    }

} 

配置文件使其生效

<context:component-scan base-package="com.demo.bigdata" />

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

如果使用了spring mvc后,如果把<aop:aspectj-autoproxy proxy-target-class="true"/>放在application.xml文件中可能会aop无效,最好把它放在dispatcher-servlet.xml文件中。

原文发布于微信公众号 - java工会(javagonghui)

原文发表时间:2018-05-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小灰灰

动手实现MVC: 4. AOP的设计与实现

设计 我们将结合日常使用的姿势来设计切面的实现方式,由于spring-mvc切面比较强大,先将切面规则这一块单独拎出来,后面单独再讲;本篇博文主要集中在如何实...

2057
来自专栏技术专栏

java程序 如何优雅地读取xml文件

1962
来自专栏https://www.cnblogs.com/L

Hadoop源码篇--Reduce篇

Reduce文件会从Mapper任务中拉取很多小文件,小文件内部有序,但是整体是没序的,Reduce会合并小文件,然后套个归并算法,变成一个整体有序的文件。

981
来自专栏码匠的流水账

springboot2自定义statsd指标前缀

springboot2引入了micrometer,1.x版本的spring.metrics.export.statsd.prefix在2版本中已经被标记为废弃,...

912
来自专栏HansBug's Lab

2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛

2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛 Time Limit: 3 Sec  Memory Limit: 64 MB S...

3308
来自专栏码匠的流水账

聊聊storm tuple的序列化

storm-2.0.0/storm-client/src/jvm/org/apache/storm/executor/ExecutorTransfer.java

644
来自专栏码匠的流水账

聊聊sentinel的ModifyRulesCommandHandler

本文主要研究一下sentinel的ModifyRulesCommandHandler

651
来自专栏Jerry的SAP技术分享

使用com.sun.imageio.plugins.png.PNGMetadata读取图片的元数据

所谓图片元数据,就是除了我们肉眼看到的图片内容外,隐藏在这些内容背后的一些技术数据。

1234
来自专栏Hongten

python开发_calendar

如果你用过linux,你可能知道在linux下面的有一个强大的calendar功能,即日历

912
来自专栏xdecode

利用Cglib实现AOP

前文讲了, 可以利用Spring, Guice等框架提供的容器实现AOP, 如果想绕过容器, 直接注入Class, 可以利用Cglib为对象加上动态代理,实现代...

1997

扫码关注云+社区