Spring AOP(面向切面编程)
发布日期:2021-04-30 21:01:39 浏览次数:143 分类:精选文章

本文共 3649 字,大约阅读时间需要 12 分钟。

Spring AOP与动态代理技术

一、Spring AOP(面向切面编程)是什么?

面向切面编程(AOP)是一种软件开发模式,旨在通过横向切入(Aspect-Oriented Programming)简化代码结构,提高开发效率。Spring AOP是基于AspectJ框架实现的,支持通过动态代理技术实现对业务逻辑的增强。常见的应用场景包括事务管理、日志记录、权限控制等。

1. AOP的基本概念

  • Joinpoint(连接点):指在Spring中可以被动态代理拦截的目标类方法。
  • Pointcut(切入点):定义要拦截的Joinpoint。
  • Advice(通知):在拦截到Joinpoint后执行的增强逻辑。
  • Target(目标):被代理的目标对象。
  • Weaving(植入):将增强代码应用到目标对象,生成代理。
  • Proxy(代理):生成的代理对象,代理目标对象的方法调用。
  • Aspect(切面):切入点和通知的结合。

2. JDK动态代理

JDK动态代理通过Java Reflection API实现,主要使用Proxy类和InvocationHandler。其优点是简单易用,但需要目标类实现接口,缺点是对接口的依赖较强。

2.1 JDK动态代理实现步骤

  • 创建接口并实现类。
  • 使用Proxy.newProxyInstance创建代理对象。
  • 提供InvocationHandler,实现拦截目标方法并执行增强逻辑。
  • 3. CGLIB动态代理

    CGLIB动态代理基于ASM框架,能够在运行时生成目标类的子类,实现更高效的代理。适用于对类进行实例级代理,且不依赖接口。

    3.1 CGLIB动态代理实现步骤

  • 创建目标类。
  • 使用CGLIB的Enhancer类生成代理类。
  • 提供MethodInterceptor实现拦截逻辑,返回增强后的结果。
  • 4. Spring动态代理(ProxyFactoryBean)

    Spring提供ProxyFactoryBean类,用于创建AOP代理。支持通过配置文件或注解定义切面、切入点和通知,实现动态代理配置。

    4.1 ProxyFactoryBean的常用属性

    • target:目标对象。
    • proxyInterfaces:代理实现的接口。
    • proxyTargetClass:是否对类进行代理。
    • interceptorNames:需要植入的通知。
    • singleton:是否为单例代理。

    5. Spring AOP的通知类型

    Spring AOP支持五种通知类型:

    • MethodBeforeAdvice(前置通知):在方法执行前执行逻辑。
    • MethodAfterReturningAdvice(后置通知):在方法执行后执行逻辑。
    • MethodInterceptor(环绕通知):在方法执行前后执行逻辑。
    • ThrowsAdvice(异常通知):在方法抛出异常时执行逻辑。
    • IntroductionInterceptor(引介通知):在目标类中添加新方法或属性。

    二、基于不同方式的动态代理实现

    1. JDK动态代理示例

    通过创建接口和实现类,使用Proxy类和InvocationHandler实现动态代理。代码如下:

    public interface StudentDao {    void add();    void update();    void delete();    void select();}public class StudentDaoImpl implements StudentDao {    public synchronized void add() {        System.out.println("添加学生...");        try {            this.wait(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("添加成功");    }    // update、delete、select 方法同理}public class MyInvocationHandler implements InvocationHandler {    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("方法执行前...");        Object result = method.invoke(target, args);        System.out.println("方法执行后...");        return result;    }}public class MyBeanFactory {    public static StudentDao getBean() {        StudentDao target = new StudentDaoImpl();        MyInvocationHandler handler = new MyInvocationHandler();        StudentDao proxy = Proxy.newProxyInstance(Proxy.class.getClassLoader(), StudentDao.class, handler, target);        return (StudentDao) proxy;    }}

    2. CGLIB动态代理示例

    通过使用CGLIB的Enhancer类生成代理类,实现对目标类的动态代理。代码如下:

    public class UserDaoImpl {    public synchronized void add() {        System.out.println("添加用户...");        try {            this.wait(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("添加成功");    }    // update、delete、select 方法同理}public class MyInterceptor implements MethodInterceptor {    public Object intercept(Method method, MethodProxy methodProxy) throws Throwable {        System.out.println("方法执行前...");        Object result = methodProxy.invoke(method);        System.out.println("方法执行后...");        return result;    }}public class MyBeanFactory {    public static UserDao getBean() {        UserDao target = new UserDaoImpl();        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(target.getClass());        enhancer.setCallback(new MyInterceptor());        UserDao proxy = enhancer.create();        return proxy;    }}

    3. Spring动态代理示例

    通过配置文件或注解定义切面,使用Spring的ProxyFactoryBean创建代理。代码如下:

    三、总结

    • JDK动态代理:简单易用,适用于接口代理。
    • CGLIB动态代理:性能更高,适用于类代理。
    • Spring动态代理:灵活可配置,支持切面和通知定义,适合复杂场景。

    选择合适的动态代理方式,根据项目需求实现AOP功能,提高开发效率和代码质量。

    上一篇:Java,SpringMVC返回值中含有等号=返回后的JSON变成\u003d的问题
    下一篇:SSH协议和Telnet协议远程登录 区别

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2026年06月15日 23时32分07秒