03-spring框架—— AOP 面向切面编程

Posted tpf386

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03-spring框架—— AOP 面向切面编程相关的知识,希望对你有一定的参考价值。

3.1 动态代理

  动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理
对象只是由代理生成工具(不是真实定义的类)在程序运行时由 JVM 根据反射等机制动态
生成的。代理对象与目标对象的代理关系在程序运行时才确立。

 3.1.1 JDK 

  动态代理的实现方式常用的有两种:使用 JDK 的 Proxy,与通过 CGLIB 生成代理。
Jdk 的动态要求目标对象必须实现接口,这是 java 设计上的要求。
  从 jdk1.3 以来,java 语言通过 java.lang.reflect 包提供三个类支持代理模式 Proxy, Method 和
InovcationHandler。

3.1.2 CGLIB  动态代理( 了解)

  CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的 Code
生成类库,它可以在运行期扩展 Java 类与实现 Java 接口。它广泛的被许多 AOP 的框架
使用,例如 Spring AOP。

  使用 JDK 的 Proxy 实现代理,要求目标类与代理类实现相同的接口。若目标类不存在
接口,则无法使用该方式实现。但对于无接口的类,要为其创建动态代理,就要使用 CGLIB
来实现。

  CGLIB 代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代

理对象。所以,使用 CGLIB 生成动态代理,要求目标类必须能够被继承,即不能是 final 的
类。

  CGLIB 经常被应用在框架中,例如 Spring ,Hibernate 等。cglib 的代理效率高于 Jdk。
项目中直接使用动态代理的地方不多。一般都使用框架提供的功能。

3.2  不使用 AOP  的开发方式 (理解)

Step1: 项目 aop_leadin1

  先定义好接口与一个实现类,该实现类中除了要实现接口中的方法外,还要再写两个非
业务方法。非业务方法也称为交叉业务逻辑:

? doTransaction():用于事务处理
? doLog():用于日志处理
然后,再使接口方法调用它们。接口方法也称为主业务逻辑。

技术图片

 

Step2:  项目 aop_leadin2

当然,也可以有另一种解决方案:将这些交叉业务逻辑代码放到专门的工具类或处理类
中,由主业务逻辑调用。

Step3: 项目 aop_leadin3

  以上的解决方案,还是存在弊端:交叉业务与主业务深度耦合在一起。当交叉业务逻辑
较多时,在主业务代码中会出现大量的交叉业务逻辑代码调用语句,大大影响了主业务逻辑
的可读性,降低了代码的可维护性,同时也增加了开发难度。
  所以,可以采用动态代理方式。在不修改主业务逻辑的前提下,扩展和增强其功能。

功能增强:

package com.bjpowernode.proxy;

import com.bjpowernode.utils.ServiceTools;

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

/**
 * Author: 动力节点
 * 2019/5/10
 */
public class MyInvocationHandler implements InvocationHandler 

    private Object target;

    public MyInvocationHandler() 
    

    public MyInvocationHandler(Object target) 
        this.target = target;
    

    /**
     * 实现业务方法的功能增强。 加入日志,事务功能
     * @param proxy 生成的代理对象
     * @param method 业务方法
     * @param args 业务方法的参数
     * @return  Object 业务方法的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 

        Object result = null;

        String mname = method.getName();
        if( "doSome".equals(mname))
            //在目标方法调用之前加入日志
            ServiceTools.doLog();

            //执行目标方法
            result = method.invoke(target, args); //doSome

            //在目标方法调用之后加入事务
            ServiceTools.doTrans();
         else 
            //doOther
            //执行目标方法
            result = method.invoke(target, args);
        





        //目标方法的执行结果
        return result;
    

代码第二部分

package com.bjpowernode;

import com.bjpowernode.proxy.MyInvocationHandler;
import com.bjpowernode.service.SomeService;
import com.bjpowernode.service.SomeServiceImpl;

import java.lang.reflect.Proxy;

/**
 * Hello world!
 *
 */
public class App 

    /*public static void main( String[] args )
    
        System.out.println( "Hello World!" );
        SomeService service = new SomeServiceImpl();
        service.doSome();
        System.out.println("====================");
        service.doOther();
    */

    public static void main( String[] args )
    
        System.out.println( "Hello World!" );
        //目标对象
        SomeService target = new SomeServiceImpl();
        //创建InvocationHandler的实现类对象
        MyInvocationHandler handler = new MyInvocationHandler(target);
        //创建代理对象
        SomeService proxy = (SomeService) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler);
        //com.sun.proxy.$Proxy0 jdk的动态代理类型
        System.out.println("proxy:"+proxy.getClass().getName());

        //通过代理对象执行业务方法,实现功能的增强
        proxy.doSome();
        System.out.println("-----------------------------");
        proxy.doOther();

    

3.3 AOP  概述

 

 

3.4 AOP 

  AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程
序运行过程。

  AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB
的动态代理。

 

以上是关于03-spring框架—— AOP 面向切面编程的主要内容,如果未能解决你的问题,请参考以下文章

spring框架学习——AOP( 面向切面编程)

Spring框架深入--AOP面向切面

Spring框架--AOP面向切面编程

Spring框架--AOP面向切面编程

Spring框架——AOP(面向切面编程)详解

动力节点Spring框架学习笔记-王鹤AOP面向切面编程