文档章节

AOP动态代理的实现机制

markGao
 markGao
发布于 2014/01/02 10:45
字数 894
阅读 1272
收藏 2

1 AOP各种的实现

AOP就是面向切面编程,我们可以从几个层面来实现AOP。

在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较。 

 

类别

机制

原理

优点

缺点

静态AOP

静态织入

在编译期,切面直接以字节码的形式编译到目标字节码文件中。

对系统无性能影响。

灵活性不够。

动态AOP

动态代理

在运行期,目标类加载后,为接口动态生成代理类,将切面植入到代理类中。

相对于静态AOP更加灵活。

切入的关注点需要实现接口。对系统有一点性能影响。

动态字节码生成

在运行期,目标类加载后,动态构建字节码文件生成目标类的子类,将切面逻辑加入到子类中。

没有接口也可以织入。

扩展类的实例方法为final时,则无法进行织入。


自定义类加载器

在运行期,目标加载前,将切面逻辑加到目标字节码里。

可以对绝大部分类进行织入。

代码中如果使用了其他类加载器,则这些类将不会被织入。


字节码转换

在运行期,所有类加载器加载字节码前,前进行拦截。

可以对所有类进行织入。



2 AOP的实现机制 
  本章节将详细介绍AOP有各种实现机制。


2.1 动态代理
  Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。使用动态代理实现AOP需要有四个角色:被代理的类,被代理类的接 口,织入器,和InvocationHandler,而织入器使用接口反射机制生成一个代理类,然后在这个代理类中织入代码。被代理的类是AOP里所说的 目标,InvocationHandler是切面,它包含了Advice和Pointcut。

2.1.1 使用动态代理
  那如何使用动态代理来实现AOP。下面的例子演示在方法执行前织入一段记录日志的代码,其中Business是代理 类,LogInvocationHandler是记录日志的切面,IBusiness, IBusiness2是代理类的接口,Proxy.newProxyInstance是织入器。
清单一:动态代理的演示

package sample.proxy;

public interface IBusiness {
    public boolean doBusiness();
}
package sample.proxy;

public interface IBusiness2 {
    public void doBusiness2();

}
package sample.proxy;


public class Business implements IBusiness, IBusiness2 {

    public boolean doBusiness() {
        System.out.println("执行业务逻辑");
        return true;
    }

    public void doBusiness2() {
        System.out.println("执行业务逻辑2");
    }

    

}
package sample.proxy;

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

public class DynamicProxyDemo {

    public static void main(String[] args) {
        // 需要代理的接口,被代理类实现的多个接口都必须在这里定义
        Class[] proxyInterface = new Class[] { IBusiness.class,
                IBusiness2.class };
        // 构建AOP的Advice,这里需要传入业务类的实例
        LogInvocationHandler handler = new LogInvocationHandler(new Business());
        // 生成代理类的字节码加载器
        ClassLoader classLoader = DynamicProxyDemo.class.getClassLoader();
        // 织入器,织入代码并生成代理类
        IBusiness2 proxyBusiness = (IBusiness2) Proxy.newProxyInstance(
                classLoader, proxyInterface, handler);
        // 使用代理类的实例来调用方法。
        proxyBusiness.doBusiness2();
        ((IBusiness) proxyBusiness).doBusiness();
    }

    /**
     * 打印日志的切面
     */
    public static class LogInvocationHandler implements InvocationHandler {

        private Object target; // 目标对象

        LogInvocationHandler(Object target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            // 执行原有逻辑
            Object rev = method.invoke(target, args);
            // 执行织入的日志,你可以控制哪些方法执行切入逻辑
            if (method.getName().equals("doBusiness2")) {
                System.out.println("记录日志");
            }
            return rev;
        }
    }

}

输出 Java代码

输出
Java代码


© 著作权归作者所有

共有 人打赏支持
上一篇: 动态代理原理
下一篇: XML Utility
markGao
粉丝 15
博文 187
码字总数 91352
作品 0
宝山
程序员
私信 提问
AOP的底层实现

原文:http://blog.csdn.net/yzllz001/article/details/54695954 AOP是目前Spring框架中的核心之一,在应用中具有非常重要的作用,也是Spring其他组件的基础。它是一种面向切面编程的思想。关...

not_in_mountain
2017/10/12
0
0
Java代理系列-动态代理

动态代理可以做什么?比如说spring的AOP,它就是以动态代理为基础实现的,AOP拦截需要的请求,然后通过代理把请求的结果返回到AOP代理类中,在代理类里就可以做很多自己想要做的事情,比如日...

Mr_river
2015/12/28
88
1
java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能...

小风89
2016/06/28
25
0
bboss aop ioc机制配置

bboss aop框架通过其动态代理模块来创建所有业务组件的代理对象实例,代理对象保持业务组件对象的引用,以便对声明式事务、注解事务、同步控制、拦截器、远程服务组件方法进行拦截调用。当业...

bboss
2010/07/14
0
0
java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能...

Zhang_Java
2016/11/17
5
0

没有更多内容

加载失败,请刷新页面

加载更多

MyBaties分页插件PageHelper的简单使用

抛出问题: 如果想要将现有的select语句改为支持分页功能的查询语句该怎么做呢? 最简单的一种做法就是将所有的select语句都加上limit来实现分页,这种做法有什么问题呢? 有没有一种简便方法...

嘴角轻扬30
16分钟前
0
0
创业公司如何快速构建高效的监控系统?

12 月 7 日,在 2018 ArchSummit 全球架构师峰会·运维与监控专场,七牛云资深运维开发工程师贺强带来了主题为《如何快速构建高效的监控系统》的内容分享。 本文是对演讲内容的实录整理。 大...

七牛云
16分钟前
0
0
Docker与自动化测试及其测试实践

Docker 与自动化测试 对于重复枯燥的手动测试任务,可以考虑将其进行自动化改造。自动化的成本在于自动化程序的编写和维护,而收益在于节省了手动执行用例的时间。简而言之,如果收益大于成本...

微笑向暖wx
17分钟前
0
0
Spring Cloud 分布式链路跟踪 Sleuth + Zipkin + Elasticsearch

随着业务越来越复杂,系统也随之进行各种拆分,特别是随着微服务架构的兴起,看似一个简单的应用,后台可能很多服务在支撑;一个请求可能需要多个服务的调用;当请求迟缓或不可用时,无法得知...

编程SHA
20分钟前
1
0
Swift-清除缓存

func removeCache (){ // 取出cache文件夹路径.如果清除其他位子的可以将cachesDirectory换成对应的文件夹 let cachePath = NSSearchPathForDirectoriesInDomains(FileMan...

west_zll
20分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部