使用 Spring AOP 注意事项

栏目: Java · 发布时间: 5年前

说实话,由于我个人某些基础不是很牢固,所以前一段时间关于 Spring Aop 踩了一个坑,其实很简单,今天就记录一下,先说结论:

不能被 Spring AOP 增强的方法:

1. 基于接口的动态代理:除 public 外的其它所有的方法,此外 public static 也不能被增强

2. 基于 CGLib 的动态代理:private、static、final 的方法,也就是只有 public 和 protected 可以,但是要注意切入点语法的配置

测试用例如下,pom 文件:

<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.11.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.11.RELEASE</version>
        </dependency>

配置文件就比较简单了:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    <context:annotation-config/>
    <context:component-scan base-package="cn.bridgeli"/>
    <aop:aspectj-autoproxy/>

</beans>

切面类:

package cn.bridgeli.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogInterceptor {
    //    @Pointcut("execution(* * com.bjsxt.service..*.add(..))")
    @Pointcut("execution(* cn.bridgeli.demo.service..*.*(..))")
    public void myMethod() {
    }


    @Before("myMethod()")
    public void before() {
        System.out.println("method before");
    }

    @Around("myMethod()")
    public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("method around start");
        pjp.proceed();
        System.out.println("method around end");
    }

}

测试类:

package cn.bridgeli.demo.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserService {

    /**
     * private方法因为修饰符访问权限的控制,无法被子类覆盖
     */
    private void method1() {
        System.out.println("method1 executed");
    }

    /**
     * final 方法无法被子类覆盖
     */
    private final void method2() {
        System.out.println("method2 executed");
    }

    /**
     * static 方法是类级别的方法,无法被子类覆盖
     */
    private static void method3() {
        System.out.println("method3 executed");
    }

    /**
     * public 方法可以被子类覆盖,因此可以被动态字节码增强
     */
    public void method4() {
        System.out.println("method4 executed");
    }

    /**
     * final 方法无法被子类覆盖
     */
    public final void method5() {
        System.out.println("method5 executed");
    }

    /**
     * protected 方法可以被子类覆盖,因此可以被动态字节码增强
     */
    protected void method6() {
        System.out.println("method6 executed");
    }

    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {

        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        System.out.println("initContext successfully");

        System.out.println("before method1");
        userService.method1();
        System.out.println("after1 method1");

        System.out.println("before method2");
        userService.method2();
        System.out.println("after1 method2");

        System.out.println("before method3");
        method3();
        System.out.println("after1 method3");

        System.out.println("before method4");
        userService.method4();
        System.out.println("after1 method4");

        System.out.println("before method5");
        userService.method5();
        System.out.println("after1 method5");

        System.out.println("before method6");
        userService.method6();
        System.out.println("after1 method6");

        if (ctx != null) {
            ctx.close();
        }
        System.out.println("close context successfully");
    }
}

参考资料:

1. http://jinnianshilongnian.iteye.com/blog/1857189

2. https://blog.csdn.net/yangshangwei/article/details/78094196

全文完,如果本文对您有所帮助,请花 1 秒钟帮忙点击一下广告,谢谢。

作 者: BridgeLi,https://www.bridgeli.cn

原文链接: https://www.bridgeli.cn/archives/592

版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


以上所述就是小编给大家介绍的《使用 Spring AOP 注意事项》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

走进搜索引擎

走进搜索引擎

梁斌 / 电子工业出版社 / 2007-1 / 49.80元

《走进搜索引擎》由搜索引擎开发研究领域年轻而有活力的科学家精心编写,作者将自己对搜索引擎的深刻理解和实际应用巧妙地结合,使得从未接触过搜索引擎原理的读者也能够轻松地在搜索引擎的大厦中邀游一番。《走进搜索引擎》作为搜索引擎原理与技术的入门书籍,面向那些有志从事搜索引擎行业的青年学生、需要完整理解并优化搜索引擎的专业技术人员、搜索引擎的营销人员,以及网站的负责人等。《走进搜索引擎》是从事搜索引擎开发的......一起来看看 《走进搜索引擎》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具