九、面向切面(方面)的编程AOP总结--笔记--码字中ing

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QQB67G8COM/article/details/81637209

知识目标:
1)理解AOP的基本概念以及原理
2)熟悉AOP的相关基本术语
3)了解AOP的相关实现者
技能目标:
利用Spring注解和XML文件配置的方式实现AOP功能

本章设计模式要点:代理模式
这里写图片描述

使用方式:

public class client {
    public static void main(String[] args) {
        Subject sub = new RealSubject();
        sub.visit();
    }
}

何时使用:想在访问一个类时做一些访问控制
如何解决:增加中间层
应用实例:1)window的快捷方式 2)Spring AOP
优点:1)职责清晰2)高扩展性3)智能化
缺点:1)由于在客户端和真是主题之间增加了代理对象,
因此有些类型的代理模式可能会造成请求的处理速度变慢。
2)实现代理模式需要额外的工作,有些代理模式的实现非常复杂。


从图中可以看出代理类与真正的实现类都是继承抽象的主题类,这样的好
处在于代理类可以与实际的类有相同的方法,可以保证客户端的使用透明性

一、AOP的基本概念

1)AOP的简介

1)基本概念:AOP即Aspect-Oriented Programming的缩写,中文名意识是面向切面(或方面)编程。它是一种思想,可在不改变程序源码的情况下为程序添加额外的功能
2)发展阶段:
静态AOP:Aspect形式,通过特定的编译器,将实现后的Aspect编译并织入到系统的静态类中
动态AOP:AOP的织入过程在系统运行开始之后进行,而不是预先编译到系统中
3)主要意图:允许通过分离应用的业务逻辑与系统服务进行内聚性的开发。应用对象只实现业务逻辑即可,并不负责其它的系统级关注点
4)应用场景:日志记录、程序跟踪、监控和优化,性能统计,安全、权限控制,应用系统的异常捕捉及处理,事务处理,缓存,持久化,懒加载(Lazy loading),内容传递,调试,资源池,同步等等

2)AOP的示例

transManager.beginTransaction();//事务开始
  //业务逻辑
transManager.commit();//事务提交

横切的逻辑就是可以看作树的年轮,有三层年轮,最里面的那层代表的是业务逻辑,包裹业务层的是事务管理逻辑,最外面那层就是性能监视逻辑
传统的代码就是在业务代码中添加一大堆重复性的横切逻辑,日志输出、性能监视等,如果项目业务变得越来越复杂,那么代码也会变得越来越复杂,不够清晰,给维护带来巨大的困难

3)AOP的术语

连接点:程序某个特定位置,比如类初始化前,初始化后,方法调用前,方法调用后等
切点:通过切点来定位特定的连接点
增强:织入到目标类连接点上的一段程序代码
目标对象:增强的织入目标类
引介:引介是一种特殊的增强,它为类添加一些属性和方法
织入:将增强添加对目标类的具体连接点上的过程
代理:一个类被AOP织入增强后,会产生一个结果类,该类融合了原类和增强逻辑的代理类
切面:由切点和增强组成,既包括了横切逻辑的定义,也包括了连接点的定义

织入方法:编译器织入、类加载器织入、动态代理织入

4)AOP的实现者

AspectJ:AspectJ是目前最完善的AOP语言,对Java编程语言的进行了扩展,定义了AOP语法,能够在编译期提供横切代码的织入。AspectJ提供了两种横切实现机制,一种称为动态横切(Dynamic Crosscutting),另一种称为静态横切(Static Crosscutting)。


AspectWerkz:基于Java的简单、动态和轻量级的AOP框架,支持运行期或类装载期织入横切代码,它拥有一个特殊的类装载器。它与AspectJ项目已经合并,第一个发布版本是AspectJ5:扩展AspectJ语言,以基于注解的方式支持类似AspectJ的代码风格。


JBoss AOP:JBoss是一个开源的符合J2EE规范的应用服务器,作为J2EE规范的补充,JBoss中引入了AOP框架,为普通Java类提供了J2EE服务,而无需遵循EJB规范。JBoss通过类载入时,使用Javassist对字节码操作实现动态AOP框架。


Spring AOP:Spring AOP使用纯Java实现,不需要专门的编译过程,不需要特殊的类装载器,它在运行期通过代理方式向目标类织入增强代码。Spring并不尝试提供最完整的AOP实现,主要侧重于提供一种和Spring IoC容器整合的AOP实现,以解决企业级开发中常见问题。

二、AOP的实现方法

Proxy实现AOP:
1、首先要创建接口

package aop.proxy;

interface IUserInterface {
    public void print();
}

2、创建实现接口的实现类

package aop.proxy;

public class UserBean implements IUserInterface{
    private String name;

    public UserBean() {}

    public UserBean(String name){
        this.name = name;
    }

    public <T> void println(T data){
        System.out.println(data);
    }

    @Override
    public void print() {
        println("输出用户名字:"+this.name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3、通过工厂模式创建代理类

package aop.proxy;

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

public class ProxyFactory implements InvocationHandler {
    private Object obj;

    /**
     * 
     * @param obj 创建目标类的代理实例
     * @return
     * 
     * newProxyInstance的三个参数:第一个参数为目标类的类加载器,第二个
     * 参数的为目标类的类实现接口,第三个参数为this就是调用InvocationHandler本身
     */
    public Object createUserProxy(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), 
                obj.getClass().getInterfaces(), this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        UserBean uBean = (UserBean)this.obj;
        Object object = null;
        if(uBean.getName() != null)
            object = method.invoke(uBean, args);
        else
            System.out.println("");
        return object;
    }

}

4、Main,调用代理对象,隐藏真实对象

package aop.proxy;

public class Main {

    public static void main(String[] args) {
        //1、通过接口创建真实类的对象
        IUserInterface realObj = new UserBean("Lee");
        //2、创建代理工厂实例
        ProxyFactory factory = new ProxyFactory();
        //3、通过代理工厂创建代理类实例
        IUserInterface proxyObj = (IUserInterface)factory.createUserProxy(realObj);
        proxyObj.print();
    }
}

知识点为学习过程中归纳整理的笔记,非原创,如有侵权请指出

猜你喜欢

转载自blog.csdn.net/QQB67G8COM/article/details/81637209