`
name327
  • 浏览: 165688 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

jdk动态代理 cglib3.0动态代理

阅读更多

先说说两者的区别

 jdk动态代理是java的标准api , 被代理的类必须实现一个或者多个接口,然后根据接口和实现类动态创建代理类,所生成的代理类是java.lang.reflect.Proxy的子类,并且也是实现类的子类(这块可能有点绕)

cglib动态代理是依靠cglib库的api ,被代理的类不用实现接口,它是以生成被代理类的子类的方法来生成代理类的。相比JDK动态代理的优势在于被代理的类不用实现任何接口就可以代理。这里要注意被代理的类不能是final。

 下面先上被代理类的代码

接口

 

package net;

public interface ISay
{
    public void say();
}

 实现类

 

package net;

public class Person implements ISay
{
    @Override
    public void say()
    {
        System.out.println("person  say.......");
    }

}

 下面让我们来看看JDK如何给这个类动态生成代理类,首先写一个代理的处理类,实现java.lang.reflect.InvocationHandler接口

看代码

 

package jdk;

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

import net.ISay;

public class MyInvocationHandler implements InvocationHandler
{
    //被代理的类
    private ISay target;

    public MyInvocationHandler(ISay target)
    {
        this.target = target;
    }
    /**
     * 
     * @param proxy 生成的代理对象,这里要注意这个参数不是被代理类。
     * 这个参数目前没有发现其作用,欢迎知道的拍砖
     * @param method 被代理对象的原始方法
     * @param args 方法调用所需要的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before");
        Object result = method.invoke(target, args);
        System.out.println("end");
        return result;
    }

}

 测试类

 

package jdk;

import java.lang.reflect.Proxy;

import net.ISay;
import net.Person;

public class Run
{
    public static void main(String[] args)
    {
        Person p=new Person();
        MyInvocationHandler mih=new MyInvocationHandler(p);
        ISay proxyPerson=(ISay) Proxy.newProxyInstance(Run.class.getClassLoader(), new Class[]{ISay.class}, mih);
        proxyPerson.say();
    }
}

 运行的测试结果

 

before

person  say.......

end

很显然我们的person类被代理了,我们可以在它原始方法的调用前后搞出一些事情

下面我们来看看cglib如何实现动态代理,注意与jdk动态代理最大的不同
代理生成类实现net.sf.cglib.proxy.MethodInterceptor接口
package 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 abstract class CglibProxy implements MethodInterceptor
{
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> t)
    {
        Enhancer e = new Enhancer();
        //设置代理的类的class
        e.setSuperclass(t);
        //设置要处理代理类方法的处理类
        e.setCallback(this);
        return (T) e.create();
    }

    /**
     * 
     * @param obj 生成的代理对象
     * @param method 被代理类的原始方法
     * @param objs 调用方法的参数
     * @param mp 代理类方法的对象,包含被代理类的原始方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable
    {
        before();
        //这里调用父类原始的方法,也就是被代理对象的原始方法
        Object result = mp.invokeSuper(obj, args);
        end();
        return result;
    }

    public abstract void before();

    public abstract void end();
}
 

这个生成代理的类,只能生成带有无参数构造方法的类,并且被代理的类不能是final 

 

测试方法

 

package cglib;

import net.Person;

public class Run
{
    public static void main(String[] args)
    {
        // 用内部类实现
        CglibProxy cp = new CglibProxy()
        {
            @Override
            public void before()
            {
                System.out.println("before");
            }

            @Override
            public void end()
            {
                System.out.println("end");
            }
        };
        Person p = cp.getProxy(Person.class);
        p.say();
    }
}

 我们来看看控制台输出了什么

before

person  say.......

end

同样也可以在person原始的say方法调用前后搞出一些事情。源码在附件,附带所需的Jar包。
cglib用的3.0版本,cglib3.0所需要依赖的asm的4.0版本才可以,asm3.0会报类兼容错误,希望大家注意。
刚学习的,欢迎大大拍砖

 

分享到:
评论

相关推荐

    Cglib3.3.0最新版jar包

    Cglib就是一种实现动态代理的方式,不同于JDK自带的Proxy,Cglib不需要目标对象实现任何接口,因此可以用于不能实现接口的对象。通过Enhancer类,我们可以指定需要代理的目标类,并提供回调方法实现动态代理逻辑。 ...

    CGLib和ASM相关jar包

    当JDK的动态代理机制无法满足需求,比如代理的目标类没有实现接口时,CGLib便派上了用场。CGLib通过生成目标类的子类来实现动态代理,这样就可以在子类中覆盖方法并添加额外的行为。CGLib的使用通常比Java反射性能更...

    spring3.0的API

    2. **JDK动态代理与CGLIB结合**:Spring 3.0可以同时使用JDK动态代理和CGLIB,提高了AOP代理的灵活性。 三、数据访问/集成 1. **JDBC模板**:提供了JdbcTemplate,简化了JDBC的使用,避免了重复的模板代码。 2. *...

    asm-all&&cglib

    2. **性能优化**:相比于基于接口的JDK动态代理,CGlib对于没有接口的类提供了更好的性能。 3. **AOP实现**:在Spring框架中,如果没有找到目标类的接口,它会使用CGlib作为动态代理技术来实现AOP。 4. **测试工具**...

    Spring3.0学习文档

    当目标对象没有接口时,Spring会使用CGLIB库生成目标类的子类作为代理,这使得无接口的类也能实现动态代理。 **事务管理**: Spring提供了一种声明式事务管理的方式,通过AOP在需要的地方自动进行事务的开启、提交...

    Java框架spring3.0

    同时,增加了对JDK动态代理和CGLIB代理的自动选择,提高了性能。 4. **数据访问增强**:引入了Spring Data Access/Integration模块,提供了对JPA、Hibernate等ORM框架更好的支持,简化了数据库操作。 5. **MVC框架...

    spring3.0 源码

    Spring AOP通过代理模式实现,可以是JDK动态代理或CGLIB代理。 三、MVC框架 Spring MVC是Spring框架的一部分,用于构建Web应用程序。在Spring 3.0中,`@RequestMapping`注解用于映射HTTP请求,`@Controller`定义...

    Spring3.0中文帮助文档

    Spring的AOP通过代理模式实现,支持JDK动态代理和CGLIB代理。 3. **MVC(Model-View-Controller)**:Spring 3.0提供了强大的Web MVC框架,用于构建RESTful Web应用程序。它支持注解驱动的控制器、模型绑定、数据...

    spring 3.0 aop 实例

    JDK代理用于接口实现类,CGLIB代理用于没有实现接口的类。 4. **配置AOP**:在Spring 3.0中,可以使用XML配置或者注解方式来声明AOP。XML配置通过`&lt;aop:config&gt;`和`&lt;aop:advisor&gt;`等元素定义切入点和通知。注解方式...

    Spring第七节课.pdf

    4. JDK动态代理和CGLIB动态代理:在Spring框架中,AOP代理可以是JDK动态代理或CGLIB代理。JDK动态代理基于接口,只能代理实现了接口的类。CGLIB代理通过继承的方式实现代理,可以代理没有实现接口的类。Spring会自动...

    Spring AOP源码深度剖析开源架构源码2021.pdf

    Spring AOP通过代理机制来实现这一功能,可以是JDK动态代理或CGLIB代理。本篇将深入探讨Spring AOP的源码,特别是代理对象的创建过程。 首先,让我们看看如何在Spring中启用基于注解的事务控制。在传统的XML配置...

    Spring3.0新特性源码

    同时,增强了代理模型,支持JDK动态代理和CGLIB代理,提高了性能。 5. **RESTful支持**:为了适应Web服务的发展,Spring 3.0提供了对RESTful风格API的全面支持。`@RequestMapping`、`@ResponseBody`等注解使得处理...

    pro spring3.0源代码

    6. **AOP代理**:Spring使用两种类型的代理——JDK动态代理和CGLIB代理,实现切面的功能。源代码中可以看到何时使用哪种代理,以及如何通过代理进行方法拦截。 7. **测试支持**:Spring提供了一套全面的测试工具,...

    百度-Java面试.pdf

    在Spring中,AOP通常通过动态代理实现,包括JDK动态代理和CGLIB。JDK动态代理基于接口,如果目标类实现了接口,则会生成代理类来拦截方法调用。而CGLIB则是在运行时生成目标类的子类,适用于未实现接口的类,但无法...

    spring3.0.5的aop使用

    Spring AOP的实现主要依赖于动态代理,它可以是JDK动态代理(接口支持)或CGLIB代理(类支持)。通过动态代理,Spring能够在不修改原始代码的情况下插入切面逻辑,实现了高度解耦的代码结构。 总结来说,Spring ...

    spring 源码

    Spring AOP通过代理模式实现,有JDK动态代理和CGLIB代理两种方式。`org.springframework.aop.framework.ProxyFactoryBean`和`org.springframework.aop.aspectj.autoproxy.AspectJAutoProxyCreator`是核心的代理类。 ...

    spring的5中事物配置 介绍spring的5中事物配置

    - **CGLIB代理**:如果目标类实现了接口,Spring默认使用JDK动态代理;如果没有接口,Spring则会使用CGLIB生成一个目标类的子类,并覆盖相应的方法来实现代理。 在配置文件中,我们可以通过`...

    跟我学spring3(总共13章)6

    JDK代理适用于接口实现类,而CGLIB代理适用于没有接口的情况。 - 注解驱动的AOP:使用`@Aspect`注解定义切面,`@Before`、`@After`、`@Around`、`@AfterReturning`、`@AfterThrowing`等注解定义通知。 3. 定义切面...

    Spring AOP IOC源码笔记.pdf

    Spring AOP基于代理实现,可以使用接口代理(JDK动态代理)或类代理(CGLIB)。 7. CGLIB: CGLIB是Spring AOP默认的代理库,用于生成目标类的子类,从而实现方法拦截。当目标类没有实现接口时,Spring会使用CGLIB...

Global site tag (gtag.js) - Google Analytics