代理模式之静态代理的稍微复杂实现---理解AOP(面向切面编程)---以具体实例来理解AOP概念

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://lixuekai.blog.csdn.net/article/details/52775761

Aspect Oriented Programming  面向切面编程。
解耦是程序员编码开发过程中一直追求的。AOP也是为了解耦所诞生。
具体思想是:定义一个切面,在切面的纵向定义处理方法,处理完成之后,回到横向业务流。
(汉字就是这么绕,一会看一下示意图,就很详细的解释这句话)

先假设,要实现如下图的业务需求:
查看公司某人的工资,但是又不能直接查看。得经过记录日志,权限校验,安全性检测,等等一些步骤之后,才可以查看工资。

查看工资是核心操作,即目标操作。
简单实现就如下图:
在一个方法把所有的全部搞定。



然后就是换一种比较好的实现方式:静态代理。

先看类继承图。


代理类里面包含目标对象的引用。图上未标出来。


先是几个操作类。

/**
 * 日志类
 */
public class Logger {
    public void logging() {
        System.out.println("logging");
    }
}

/**
 * 安全性检查
 */
public class Security {
    public void security() {
        System.out.println("security");
    }
}

/**
 * 权限类
 */
public class Privilege {
    private String access;

    public String getAccess() {
        return access;
    }

    public void setAccess(String access) {
        this.access = access;
    }
}

然后就是:目标接口类。

/**
 * 目标接口:
 * 包含目标方法的声明
 */
public interface SalaryService {
    /**
     * 目标方法
     */
    void showSalary();
}

接着是:真实目标实现类。

/**
 * 目标对象类实现目标接口.
 * 继而实现目标方法。
 */
public class SalaryServiceImpl implements SalaryService {

    /**
     * 实现目标接口的目标方法(即目标操作)
     */
    @Override
    public void showSalary() {
        System.out.println("正在查看工资");
    }
}

然后就是:代理对象实现类。

/**
 * 代理对象类也实现目标接口
 * 继而实现目标方法。
 */
public class SalaryServiceProxy implements SalaryService {

    private Privilege privilege;
    private Logger logger;
    private Security security;
    private SalaryService target;

    public SalaryServiceProxy(Privilege privilege, Logger logger, Security security, SalaryService target) {
        this.privilege = privilege;
        this.logger = logger;
        this.security = security;
        this.target = target;
    }

    /**
     * 实现目标接口的目标方法(即目标操作)
     * 并对目标方法进行扩展
     */
    @Override
    public void showSalary() {
        this.logger.logging();
        this.security.security();
        if (this.privilege.getAccess().equals("admin")) {
            this.target.showSalary();//目标对象的目标方法
        } else {
            System.out.println("您没有该权限");
        }
    }
}

最后是:测试类。

public class MainTest {
    public static void main(String[] args) {
        Logger logger = new Logger();//日志
        Security security = new Security();//安全性
        Privilege privilege = new Privilege();//权限
        privilege.setAccess("admin");

        SalaryService proxy = new SalaryServiceProxy(privilege, logger, security, new SalaryServiceImpl());
        proxy.showSalary();

    }
}


具体文件的摆放示意图:



测试执行结果:



然后就是:

面向切面编程的具体思想是:定义一个切面,在切面的纵向定义处理方法,处理完成之后,回到横向业务流。(不要在意到底是横着还是竖着。差别就是横切还是竖切,都一样的。)



上述实现方式,就可以各自实现各自的,互不影响。低耦合。

缺点还是:静态代理。

以后会继修改为动态代理来实现。





展开阅读全文