首页 > 编程语言 > 详细

Spring---AOP

时间:2020-03-02 20:16:49      阅读:62      评论:0      收藏:0      [点我收藏+]

面向切面编程(Aspect Oriennted Programing)

相关概念

  概述:面向切面编程是通过预编译和运行期间动态代理实现程序功能统一维护的一种技术。

     简单来说,就是把程序重复的代码抽取出来,在需要执行的时候使用动态代理技术,在不修改源代码的基础上,对我们已有的方法进行增强。

  为什么要使用AOP:利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合降低,提高程序的重用性,同时提高了开发的效率。

  作用:在程序运行期间,不修改源码对已有的方法增强

  优势:1.减少重复代码;2.提高开发效率;3.维护方便。

  实现方式:JDK动态代理和cglib动态代理

 

代理模式

  结构图:

  技术分享图片

 

  1.静态代理

    优点:"业务类"只关注"业务逻辑",以保证重用性(代理的共有优点)

    缺点:

      规模小:"代理对象"只受一种委托;如果"目标对象"很多,需一一代理,故不适用于大程序。  

      难扩展:若接口增一法,则实现类要改、代理类亦改。  

 

  2.cjlib动态代理

    使用cglib开源包,将代理对象的class文件加载进来,利用字节码技术修改class文件的字节码生成子类,进而实现代理类。

    包:com.springsource.net.sf.cglib-2.2.0.jar(在spring AOP用的包里就有)  

     <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>3.2.2</version>
        </dependency>

 

  3.jdk动态代理   

    • JDK动态代理使用反射技术,生成实现代理接口的匿名类。  
    • 代理类实现InvocationHandler接口,该接口中有个方法“invoke”,处理 "动态代理类" 的方法调用。  
    • 调用时,需要使用Proxy.newProxyInstance()方法创建代理类  

   动态代理使用时机

    

  代码实现三种代理:

 

//卖家类(类似于工商局),实现卖家接口,才具备卖车资格
public interface Seller {
    void sell();
}

  

//汽车工厂(目标类)实现Seller接口,
public class AutoFactory implements Seller{
    public void sell() {
        System.out.println("卖新能源汽车");
    }
}

  

/**
 * 静态代理类(4S店)
 * 目标:4S店使用静态代理,代理卖汽车厂家的车,实现收取买车前和买车后的管理费
 */
public class FourShop implements Seller {
    private Seller realSeller;  //实际卖车的人

    public FourShop(Seller realSeller) {
        this.realSeller = realSeller;
    }

    public void sell() {
        System.out.println("4s店代理买车,收取管理费");
        realSeller.sell();
        System.out.println("4s店代理买车,收取返点");
    }

    //测试
    public static void main(String[] args) {
        Seller seller = new FourShop(new AutoFactory());
        seller.sell();
    }
}

  

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Cglib动态代理:
 *      代理类一本作为一个拦截器使用,实现MethodInterceptor接口,重写intercept方法,在方法中使用Method的形参调用invoke()方法,将目标类对象作为参数传递
* Enhancer:代码增强类 */ public class CglibProxy implements MethodInterceptor { private Seller realSell; public CglibProxy(Seller realSell) { this.realSell = realSell; }
  
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("CglibProxy收费--before");
        method.invoke(realSell);
        System.out.println("CglibProxy收费--after");
        return null;
    }

//测试 public static void main(String[] args) { //Cglib动态代理,需用Enhancer增强类 Enhancer enhancer = new Enhancer(); //指定代理的类为汽车工厂 CglibProxy interceptor=new CglibProxy(new AutoFactory()); enhancer.setCallback(interceptor); //设置超类 enhancer.setSuperclass(Seller.class); //创建一个超类对象 Seller seller = (Seller)enhancer.create(); seller.sell(); } }

  

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

/**
 * JDK动态代理,实现InvocationHandler接口和重写invoke方法
 */
public class JDKProxy implements InvocationHandler {
    private Seller realSeller;

    public JDKProxy(Seller realSeller) {
        this.realSeller = realSeller;
    }

    // InvocationHandler(请求处理者)
    // invoke(...):核心方法——请求
    // 集中处理 "动态代理类" 的所有方法调用
    // 参数1:代理类的实例,类型如:class com.sun.proxy.$Proxy4
    // 参数2:代理要执行的方法
    // 参数3:方法的参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK动态代理前");
        method.invoke(realSeller);
        System.out.println("JDK动态代理后");
        return null;
    }

    public static void main(String[] args) {
        Seller realSeller=new AutoFactory();
        // - 参数1:ClassLoader loader
        ClassLoader classLoader = realSeller.getClass().getClassLoader();
        // - 参数2:Class<?>[] interfaces【(被代理)接口数组(一个委托类可以实现多个接口)】
        Class<?>[] interfaces = realSeller.getClass().getInterfaces();
        // - 参数3:InvocationHandler jdkProxy
        JDKProxy jdkProxy = new JDKProxy(realSeller);
        Seller proxyInstance = (Seller)Proxy.newProxyInstance(classLoader, interfaces, jdkProxy);
        proxyInstance.sell();
    }
}

  

 

 

 

     

Spring---AOP

原文:https://www.cnblogs.com/jasonjson/p/12397704.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!