Aspect Oriented Programming 面向切面编程

1.

业界 AOP 实际上 OOP (面向对象编程 ) 延伸 ----  OOP编程语言、 AOP设计思想,下面给出一张AOP的设计思想图。

09Spring_AOP介绍和java本身的动态代理以及cglib代理

看左边的的图,UserDao里面定义了两个方法,save方法还有delete方法,我想在执行这两个方法的时候都能打印出日志。java的方法是采用继承,我们写一个抽象的类(Basedao),里面定义了public void writeLog()这个打印日志的方法。然后让UserDao这个类继承BaseDao这样可以实现我要的功能,但是,这么做的话,有一个问题,这样做就破坏了类的结构,因为一个类继承了另外一个类的话会相当于多了一些父类的方法,这样做不好,是属于侵入式复用。所以提出了动态代理,AOp的概念。横向抽取代码复用,基于代理技术,在不修改原有对象代码情况下,对原有对象方法功能进行增强! ---------- AOP 思想

 

 

2.

接下来介绍一下Spring框架是怎么实现的AOp的

09Spring_AOP介绍和java本身的动态代理以及cglib代理

 

3.

接下来介绍AOP的相关术语:

09Spring_AOP介绍和java本身的动态代理以及cglib代理

4.Aop的底层实现:

Spring AOP 代理实现有两种: JDK动态代理 和 Cglib框架动态代理

JDK API 内置 ---- 通过 Proxy类,为目标对象创建代理 (必须面向接口代理)

 

JDK API 内置 ---- 通过 Proxy类,为目标对象创建代理 (必须面向接口代理 )
public class JdkProxyFactory implements InvocationHandler {
    // 被代理对象
    private Object target;

    // 在构造方法对象时,传入被代理对象
    public JdkProxyFactory(Object target) {
        this.target = target;
    }

    // 创建代理
    public Object createProxy() {
        // 三个参数: 类加载器、 实现接口、 invocationhandler
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("记录日志!!!!!!");
        // 调用目标真实方法
        // target 被代理对象, args 方法参数 , method 被调用的方法
        return method.invoke(target, args);
    }
}

 

 

 

因为采用java的动态代理的话必须要求有接口所以为了解决这个问题,提出了Cglib 动态代理

 

CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

 

 

 

Cglib 不但可以对接口进行代理,也可以对目标类对象,实现代理 (解决了 Jdk 只能对接口代理问题 )

 

下载网址: http://sourceforge.net/projects/cglib/files/ 

 

-------  在spring3.2版本 core包中内置cglib  

09Spring_AOP介绍和java本身的动态代理以及cglib代理

 

 

所以我们可以直接使用,而不需要特意去导入Cglib的包, 我们编写一个Cglib动态代理的程序:

结构图如下:

09Spring_AOP介绍和java本身的动态代理以及cglib代理

CglibproxyFactory.java是代理类。CglibProcyTest是Junit的测试类,ProductDAo是被代理的对象。CglibproxyFactory这个代理类仿照前面的java原生代理(JdkProxyFactory )写。

CglibProxyFacory的代码如下:

package b_cglib;
import java.lang.reflect.Method;

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

/*
 * Create by 沈晓权
 * Create on 2016年7月26日下午10:32:55
 */
public class CglibProxyFactory  implements MethodInterceptor{
private Object target;
/**
 * 
 */
public CglibProxyFactory( Object object) {
this.target=object;
}

//创建代理的方法
public Object createProxy()
{//1.创建Enhancer对象
    Enhancer enhancer=new Enhancer();
    //2.cglib创建代理,对目标对象,创建子类(cglib实现代理是通过子类这种形式创建的)
 enhancer.setSuperclass(target.getClass());
//3.这一步相当于之前的JdkProxyFactory中的Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
最后那个this传入

enhancer.setCallback(
this); return enhancer.create(); } /* (non-Javadoc) * @see org.springframework.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[],
org.springframework.cglib.proxy.MethodProxy)
*/ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//执行要代理的方法 System.out.print(
"记录日志");
//执行真正的方法,
return method.invoke(target, args); } }

 ProductDAo的代码:

//没有接口,就不能使用JDK的动态代理,我们使用
public class ProductDAo {
    public void addProduct()
    {
        System.out.print("增加商品");
        
    }
    public void deleteProduct()
    {
        
        System.out.print("删除商品");
        
    }

}

 

JUnit的代码:

public class CglibProxyTest {

@Test
public void haveproxy()
{//1.创建目标对象
    ProductDAo productDAo=new ProductDAo();    
//2.创建代理类,因为没有接口所以这里使用ProductDAo proxy这么写的
ProductDAo proxy=(ProductDAo)new CglibProxyFactory(productDAo).createProxy();
proxy.addProduct();
proxy.deleteProduct();
}
}

 

 

 

 

 

 

 

Cglib 创建代理思想: 对目标类创建子类对象

设置 superClass 对哪个类创建子类 (类似 JDK代理 接口)

设置 callback 实现增强代码 (类似 JDK代理 InvocationHandler

 

cglibcallback函数中,要执行被代理对象的方法

method.invoke(target, args); 等价于 methodProxy.invokeSuper(proxy, args); 

 

09Spring_AOP介绍和java本身的动态代理以及cglib代理

 

相关文章:

  • 2021-07-19
  • 2021-12-10
  • 2022-12-23
  • 2021-07-25
  • 2021-12-24
  • 2022-02-28
  • 2021-10-02
  • 2021-09-17
猜你喜欢
  • 2022-02-10
  • 2021-06-27
  • 2021-10-22
  • 2021-08-24
  • 2021-08-22
  • 2022-12-23
  • 2021-07-19
相关资源
相似解决方案