博客
关于我
Spring篇-AOP
阅读量:146 次
发布时间:2019-02-27

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

AOP(面向切面编程)是一种软件开发的编程范式,旨在通过动态代理和切面技术,隔离系统中的关注点,提升系统的可维护性和可扩展性。AOP通过在不修改源代码的情况下,动态地在主干功能中注入新的功能,降低了代码之间的耦合度,提高了开发效率。

AOP的概念

AOP的核心思想是通过在业务逻辑的各个部分(即切面)中插入额外的逻辑(通知),从而实现对系统流程的监控、记录或修改。这种方式使得代码的耦合度降低,系统的可维护性提高,开发效率也随之提升。

AOP的通俗描述是:在不修改现有代码的情况下,通过动态方式在主干功能中注入新功能。这意味着可以在不影响现有业务逻辑的情况下,添加日志记录、事务管理、权限验证等功能。

AOP底层原理

AOP的实现通常依赖于动态代理技术。动态代理在Java中有两种实现方式:

  • 基于接口的动态代理(JDK动态代理):适用于目标对象实现了接口的情况。Java的Proxy类提供了newProxyInstance方法来创建动态代理对象。这种方式通过生成一个代理类,代理目标对象的方法调用。

  • 基于类的动态代理(CGLIB动态代理):适用于目标对象没有接口的情况。CGLIB动态代理通过生成一个继承目标类的子类来实现动态代理。

  • JDK动态代理代码实现

    在实际开发中,JDK动态代理是最常用的实现方式。以下是使用JDK动态代理实现AOP的一种常见做法:

    代码实现

    public interface UserDao {    int add(int a, int b);    String update(String id);}public class UserDaoImpl implements UserDao {    @Override    public int add(int a, int b) {        System.out.println("执行了add方法");        return a + b;    }    @Override    public String update(String id) {        System.out.println("执行了update方法");        return id;    }}public class JDKProxyTest {    public static void main(String[] args) {        Class[] interfaces = {UserDao.class};        UserDao dao = (UserDao) Proxy.newProxyInstance(            JDKProxyTest.class.getClassLoader(),            interfaces,            new UserDaoProxy(new UserDaoImpl())        );        System.out.println(dao.add(10, 20));        System.out.println("---------------------------------------------");        System.out.println(dao.update("cVzhanshi"));    }}public class UserDaoProxy implements InvocationHandler {    private Object obj;    public UserDaoProxy(Object obj) {        this.obj = obj;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)        throws Throwable {        System.out.println("方法之前执行...." + method.getName() + " :传递的参数... " + Arrays.toString(args));        Object res = method.invoke(obj, args);        System.out.println("方法之后执行...." + obj);        return res;    }}

    运行效果

    运行上述代码,可以看到输出结果如下:

    方法之前执行....add :传递的参数... [10, 20]执行了add方法11方法之后执行....UserDaoImpl@16:29----------------------------------------------方法之前执行....update :传递的参数... [cVzhanshi]执行了update方法cVzhanshi方法之后执行....UserDaoImpl@16:29

    AOP术语

    在AOP中,主要涉及以下术语:

  • 连接点:系统中能够被增强的方法或代码位置。

  • 切入点:实际被增强的方法或代码位置。

  • 通知:在增强的逻辑中,用于实现特定功能的代码块。通知有多种类型:

    • 前置通知:在方法执行前调用。
    • 后置通知:在方法执行后调用(返回通知)。
    • 最终通知:在方法执行后总是调用。
    • 异常通知:在方法抛出异常时调用。
    • 环绕通知:在方法执行前后都有逻辑。
  • 切面:指将通知应用到切入点的过程。

  • AOP操作

    在实际项目中,Spring框架通常基于AspectJ实现AOP操作。AspectJ是一个独立的AOP框架,与Spring无关,但常常与Spring一起使用。

    基于注解的AOP操作

    在使用AspectJ实现AOP时,主要使用以下注解:

  • @Before:表示前置通知。
  • @AfterReturning:表示返回通知。
  • @After:表示最终通知。
  • @AfterThrowing:表示异常通知。
  • @Around:表示环绕通知。
  • 以下是一个简单的示例:

    public class User {    public void add() {        System.out.println("执行add方法");    }}public class UserProxy {    @Before(value = "execution(*User.add())")    public void before() {        System.out.println("方法执行前....");    }    @After(value = "execution(*User.add())")    public void after() {        System.out.println("方法执行后....");    }    @Around(value = "execution(*User.add())")    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {        System.out.println("环绕前....");        proceedingJoinPoint.proceed();        System.out.println("环绕后....");    }}

    在Spring中配置:

    配置文件实现

    在Spring的配置文件中,可以通过 <aop:config>标签来配置切面。以下是一个简单的示例:

    补充

  • 相同切入点抽取:当多个增强类使用相同的切入点时,可以通过创建公共切入点方法来提高代码复用性。

  • 切面优先级:在多个增强类中定义相同的切入点时,可以通过在增强类上添加@Order注解来设置优先级,优先级越小的切面优先生效。

  • 通过以上方法,开发者可以灵活地使用AOP技术来实现系统的各项需求,提升系统的可维护性和扩展性。

    转载地址:http://rrkb.baihongyu.com/

    你可能感兴趣的文章
    Node-RED中实现HTML表单提交和获取提交的内容
    查看>>
    node.js 怎么新建一个站点端口
    查看>>
    Node.js 文件系统的各种用法和常见场景
    查看>>
    node.js 配置首页打开页面
    查看>>
    node.js+react写的一个登录注册 demo测试
    查看>>
    Node.js中环境变量process.env详解
    查看>>
    Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
    查看>>
    Node.js的循环与异步问题
    查看>>
    nodejs libararies
    查看>>
    nodejs 运行CMD命令
    查看>>
    nodejs-mime类型
    查看>>
    nodejs中Express 路由统一设置缓存的小技巧
    查看>>
    NodeJs学习笔记001--npm换源
    查看>>
    Node入门之创建第一个HelloNode
    查看>>
    NOIp2005 过河
    查看>>
    NOPI读取Excel
    查看>>
    NoSQL&MongoDB
    查看>>
    NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty()
    查看>>
    npm run build 失败Compiler server unexpectedly exited with code: null and signal: SIGBUS
    查看>>
    npm run build部署到云服务器中的Nginx(图文配置)
    查看>>