Spring框架_4---AOP

1.Spring AOP(面向切面编程)是什么? 面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。SpringAOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。 AOP 的全称是“Aspect Oriented Programming”,即面向切面编程,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。 AOP 采取横向抽取机制,取代了传统...
摘要由CSDN通过智能技术生成

1.Spring AOP(面向切面编程)是什么?

     面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目

的。

      AOP 的全称是“Aspect Oriented Programming”,即面向切面编程,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。

     AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。目前最流行的 AOP 框架有两个,分别为 Spring AOP

和 AspectJ。

     Spring AOP 使用纯 Java 实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类植入增强的代码。

     AspectJ 是一个基于 Java 语言的 AOP 框架,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。AspectJ 扩展了 Java 语言,提供了一个专门的编译器,在编译时提供横向代码的植

入。为了更好地理解 AOP,就需要对 AOP 的相关术语有一些了解,这些专业术语主要包含 Joinpoint、Pointcut、Advice、Target、Weaving、Proxy 和 Aspect,它们的含义如下表所示。

名称

说明

Joinpoint(连接点)

指那些被拦截到的点,在 Spring 中,可以被动态代理拦截目标类的方法。

Pointcut(切入点)

指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。

Advice(通知)

指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。

Target(目标)

指代理的目标对象。

Weaving(植入)

指把增强代码应用到目标上,生成代理对象的过程。

Proxy(代理)

指生成的代理对象。

Aspect(切面)

切入点和通知的结合。

2.Spring JDK动态代理

     JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的。下面通过具体的案例演示 JDK 动态代理的使用:

     1. 创建项目

     2. 创建接口 StudentDao           

         在项目的 src 目录下创建一个名为 com.wangxing.jdkproxydemo1.dao的包,在该包下创建一个 StudentDao接口,编辑后如下所示:

package com.wangxing.jdkproxydemo1.dao;

public interface StudentDao {
    public void add(); // 添加

    public void update(); // 修改

    public void delete(); // 删除

    public void find(); // 查询
}

     3. 创建实现类 StudentDaoImpl

          在com.wangxing.jdkproxydemo1.dao.impl包下创建 CustomerDao 接口的实现类 StudentDaoImpl,并实现该接口中的所有方法,如下所示。

package com.wangxing.jdkproxydemo1.dao.impl;
import com.wangxing.jdkproxydemo1.dao.StudentDao;
public class StudentDaoImpl implements StudentDao {
    @Override
    public void add() {
        System.out.println("添加学生...");
    }
    @Override
    public void update() {
        System.out.println("修改学生...");
    }
    @Override
    public void delete() {
        System.out.println("删除学生...");
    }
    @Override
    public void find() {
        System.out.println("查询学生...");
    }
}

     4. 创建切面类 MyAspect

          在 src 目录下,创建一个名为com.wangxing.jdkproxydemo1.jdkaspect的包,在该包下创建一个切面类 MyAspect,编辑后如下所示。

package com.wangxing.jdkproxydemo1.jdkaspect;

public class MyAspect {
    public void myBefore() {
        System.out.println("方法执行之前");
    }
    public void myAfter() {
        System.out.println("方法执行之后");
    }
}

            上述代码中,在切面中定义了两个增强的方法,分别为 myBefore() 方法和 myAfter() 方法,用于对目标类(CustomerDaoImpl)进行增强。

     5. 创建代理类 MyBeanFactory

         在 com.wangxing.jdkproxydemo1.jdkaspect包下创建一个名为 MyBeanFactory 的类,在该类中使用 java.lang.reflect.Proxy 实现 JDK 动态代理,如下所示。

package com.wangxing.jdkproxydemo1.jdkaspect;

import com.wangxing.jdkproxydemo1.dao.StudentDao;
import com.wangxing.jdkproxydemo1.dao.impl.StudentDaoImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyBeanFactory {
    public static StudentDao getBean() {
        // 准备目标类
        final StudentDao studentDao = new StudentDaoImpl();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 使用代理类,进行增强
        return (StudentDao) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                new Class[] { StudentDao.class }, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method,
                                         Object[] args) throws Throwable {
                        myAspect.myBefore(); // 前增强
                        Object obj = method.invoke(studentDao, args);
                        myAspect.myAfter(); // 后增强
                        return obj;
                    }
                });
        }
}

            上述代码中,定义了一个静态的 getBean() 方法,这里模拟 Spring 框架的 IoC 思想,通过调用 getBean() 方法创建实例,第 14 行代码创建了 StudentDao 实例。

第 16 行代码创建的切面类实例用于调用切面类中相应的方法;第 18~26 行就是使用代理类对创建的实例 customerDao 中的方法进行增强的代码,其中 Proxy 的 newProxyInstance() 方法的第

一个参数是当前类的类加载器,第二参数是所创建实例的实现类的接口,第三个参数就是需要增强的方法。

            在目标类方法执行的前后,分别执行切面类中的 myBefore() 方法和 myAfter() 方法。

     6. 创建测试

@Test
public void test1(){
    //得到代理对象
    StudentDao studentDao=MyBeanFactory.getBean();
    //得到普通对象
    //StudentDao studentDao=new StudentDaoImpl();
    studentDao.add();
}

             上述代码中,在调用 getBean() 方法时,获取的是 StudentDao  类的代理对象,然后调用了该对象中的方法。

     7. 运行项目并查看结果

3.Spring CGLlB动态代理

     通过《Spring JDK动态代理》教程的学习可以知道,JDK 动态代理使用起来非常简单,但是它也有一定的局限性,这是因为 JDK 动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值