`
zl198751
  • 浏览: 278450 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

OP有三种织入切面的方法:其一是编译期织入 ,这要求使用特殊的Java编译器,AspectJ是其中的代表者;其二是 类装载期织入 ,而这要求使用特殊的类装载器,AspectJ和AspectWerkz是其中的代表者;其三为动态代理织入 ,在运行期为目标类添加增强生成 子类的方式,Spring AOP采用动态代理织入切面。
Spring AOP使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供基于接口的代理,不支持类的代理。


切入点一般是方法调用之前,之后或者两端。接下来分别介绍下JDK的动态代理和CGLib的动态代理。


JDK动态代理


JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 InvocationHandler。

InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类 的代码,动态将横切逻辑和业务逻辑编织在一起。
Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例。


接口


package test.aop.jdk;

public interface Bussiness {

    public void doFirst(String thing);
    
    public void doSecond(String thing);
    
}




实现类:

package test.aop.jdk;

public class BussinessImpl implements Bussiness{

    @Override
    public void doFirst(String thing) {
        System.out.println("Do First Bussiness:" + thing);
        
    }

    @Override
    public void doSecond(String thing) {
        System.out.println("Do Second Bussiness:" + thing);
    }

    
}




代理类:

package test.aop.jdk;

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

public class BussinessHandle implements InvocationHandler{
    
    public Object target;
    
    public BussinessHandle(Object target) {//①target为目标的业务类
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        System.out.println("add aspect before method invocation.");
        Object o = method.invoke(this.target, args); //②通过反射方法调用目标业务类的业务方法
        System.out.println("add aspect after method invocation.");
        
        return o;
    }
}



实现InvocationHandler接口,该接口定义了一个 invoke(Object proxy, Method method, Object[] args)的方法,proxy是代理实例,一般不会用到;method是代理实例上的方法,通过它可以发起对目标类的反射调用;args是通过代理类传入 的方法参数,在反射调用时使用。



调用:

package test.aop.jdk;

import java.lang.reflect.Proxy;

public class JDKDynamicProxy {

    public static void main(String[] args) {
        Bussiness b = new BussinessImpl();
        
        BussinessHandle handle = new BussinessHandle(b);
        
        Bussiness proxy = (Bussiness) Proxy.newProxyInstance(b.getClass().getClassLoader(), 
                b.getClass().getInterfaces(), handle);
        
        
        proxy.doFirst("Hello World");
        proxy.doSecond("Bye Bye");
    }
}


 

CGLib动态代理


被代理的类:

package test.aop.cglib;

public class BussinessImpl{

    public void doFirst(String thing) {
        System.out.println("Do First Bussiness:" + thing);
        
    }

    public void doSecond(String thing) {
        System.out.println("Do Second Bussiness:" + thing);
    }

    
}




代理类:

package test.aop.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibDynamicProxy implements MethodInterceptor{

    private Enhancer enhancer = new Enhancer();
    
    public Object getProxy(Class c) {
        enhancer.setSuperclass(c); // ① 设置需要创建子类的类
        enhancer.setCallback(this);
        return enhancer.create(); // ②通过字节码技术动态创建子类实例
    }
    
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2,
            MethodProxy arg3) throws Throwable {
        
        System.out.println("add aspect before method invocation.");
        arg3.invokeSuper(arg0, arg2);
        System.out.println("add aspect after method invocation.");
        
        return null;
    }

    public static void main(String[] args) {
        CGLibDynamicProxy proxy = new CGLibDynamicProxy();
        BussinessImpl business = (BussinessImpl) proxy.getProxy(BussinessImpl.class);
        business.doFirst("Hello World");
        business.doSecond("Bye Bye");
        
    }
    
}



 

intercept(Object obj, Method method, Object[] args,MethodProxy proxy)是CGLib定义的Inerceptor接口的方法,obj表示代理后的子类 ,method为父类方法的反射对象,args为方法的动态入参, 而proxy为代理类实例。一般使用 proxy进行调用父类方法,这样更快。



JDK和CGLib的速度比较:


从jdk1.5以后包括1.5,jdk(去掉安全检查后)和cglib基本相同,cglib会快一点。




分享到:
评论

相关推荐

    java aop、ioc 、注解 实例 Demo

    Java AOP(面向切面编程)、IOC(控制反转)和注解是Java开发中的核心概念,尤其在Spring框架中被广泛应用。本实例Demo将深入探讨这三个主题,通过具体代码示例帮助理解它们的工作原理和实际用途。 AOP,即面向切面...

    aop.zip_884AOP_java aop原理_javaaop原理

    Java AOP(面向切面编程)是软件设计中的一个重要概念,它允许程序员定义“切面”,这些切面封装了特定的、与业务逻辑不直接相关的关注点,如日志、事务管理、性能监控等。AOP的核心思想是将横切关注点从核心业务...

    Aop.rar_aop_java aop 例 proxy

    在Java编程领域,AOP(Aspect Oriented Programming,面向切面编程)是一种强大的设计模式,它允许程序员将关注点从核心业务逻辑中分离出来,如日志、事务管理、性能监控等。AOP的主要思想是将这些横切关注点与主...

    Java实现aop案例

    Java AOP(面向切面编程)是一种编程范式,它允许程序员定义“切面”,这些切面封装了特定关注点的代码,如日志、事务管理、权限检查等。这样可以将这些关注点与核心业务逻辑分离,提高代码的可读性和可维护性。在...

    spring-aop.rar_java aop_spring aop

    【标题】"spring-aop.rar_java aop_spring aop" 涉及的主要知识点是Spring框架中的面向切面编程(AOP)以及Java基础知识。这个压缩包可能包含了一个简单的Spring AOP应用示例,同时也涵盖了Java的一些核心概念,如...

    AOP.rar_java aop_oracle

    Java AOP(面向切面编程)是一种编程范式,它允许程序员定义“切面”,这些切面封装了特定关注点的实现,如日志、事务管理或安全性。在本示例中,`AOP.rar` 文件显然包含了与Java AOP相关的代码实现,可能是为了改善...

    java AOP aspectjrt-1.8.14 AOP核心大集合

    Java AOP(面向切面编程)是一种编程范式,它允许程序员定义“切面”,这些切面封装了特定的关注点,如日志、事务管理或性能监控。在Java世界中,AspectJ是一个强大的AOP框架,它扩展了Java语言,提供了静态和动态...

    java aop拦截方法类前后添加日志

    在Java开发中,AOP(面向切面编程)是一种强大的设计模式,它允许程序员将关注点从业务逻辑中分离出来,比如日志记录、事务管理、性能监控等。本话题聚焦于如何使用Java AOP来在方法执行前后插入日志记录,这有助于...

    java AOP实现字段加密/解密

    Java AOP(面向切面编程)是一种编程范式,它允许程序员定义“切面”,这些切面封装了特定关注点的代码,如日志、事务管理或安全性,从而提高代码的可重用性和模块化。在Java中,Spring框架提供了对AOP的强大支持。 ...

    java AOP接口防刷代码

    Java AOP(面向切面编程)是Spring框架中的一个重要特性,它允许我们在不修改源代码的情况下,对程序进行功能增强,比如日志记录、权限控制、事务管理等。在这个"java AOP接口防刷代码"中,我们很可能是找到了一种...

    Java AOP 公共异常处理,一个没有try的项目。.zip

    Java AOP(面向切面编程)是Java编程领域中的一个重要概念,它允许程序员定义横切关注点,并将这些关注点与应用程序的业务逻辑分离。在实际开发中,公共异常处理是一个常见的AOP应用场景,用于统一处理可能出现的...

    AOP.rar_aop-bc04_it_java aop

    java aop bible must to read it

    java AOP重要概念.jpg

    java AOP重要概念.jpg

    基于AspectJ的Java AOP项目设计源码

    该项目为君匡出品,采用AspectJ技术实现的Java AOP项目示例源码。项目包含143个文件,其中84个为Java源代码文件,34个为XML配置文件,18个为Markdown文档,5个为AspectJ注解文件,1个为Git忽略配置文件,1个为YAML...

    java AOP原理以及实例用法总结

    Java AOP原理以及实例用法总结 Java AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想,旨在满足高耦合低内聚的六大原则。AOP通过将横切关注点(cross-cutting concerns)与业务逻辑分离,来提高...

    java aop demo

    Java AOP(面向切面编程)是Java编程领域中一种重要的设计模式,它允许程序员在不修改源代码的情况下,插入新的行为或增强已有功能。在本示例中,我们将探讨如何在Spring Boot框架中实现AOP,从而提高代码的可维护性...

    Java利用spring aop进行监测方法执行耗时

    使用 Spring AOP 进行方法耗时监测的好处有以下几点: 1. 代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 ...

    Aop.rar_aop_java aop

    AOP(Aspect Oriented Programming,面向切面编程)是Java编程领域中的一种设计模式,它扩展了传统的面向对象编程,允许程序员定义“方面”,这些方面可以包含关注点,如日志、事务管理、性能监控等,这些关注点通常...

    java Spring aop所需Jar包

    Java Spring AOP(面向切面编程)是一种强大的设计模式,它允许程序员在不修改源代码的情况下,通过插入切面来增强或修改已有代码的行为。在Spring框架中,AOP主要用于日志记录、性能监控、事务管理等场景。下面将...

Global site tag (gtag.js) - Google Analytics