Spring(七)动态代理

在上一篇博客中简单写了一下静态代理,这里主要讲一下动态代理

动态代理主要有两种

JDK动态代理   CGLIB动态代理

那这两种代理有什么区别呢?

(根据自己的理解总结)

1.JDK动态代理

他的特点是:目标对象必须有接口

他的实质是:创建了接口的一个实现类

他运行的时机:程序运行时

2.CGLIB动态代理

他的特点是:在一个类型没有接口的情况下进行代理

他的实质是:在内存中构建目标类型的子类

他运行的时机是:编译时

简单介绍完这两种代理后,就用个例子具体看怎么实现动态代理

先做JDK动态代理

准备一个接口ISomeService,接口中有一个方法doSome(),和一个这个接口的实现类SomeServiceImpl,并重写其中的方法,具体代码如下

package demo15;

/**
 * Created by mycom on 2018/3/8.
 */
public interface ISomeService
{
    public void doSome();
}
package demo15;

/**
 * Created by mycom on 2018/3/8.
 */
public class SomeServiceImpl implements ISomeService {
    public void doSome() {
        System.out.println("十点十分的复习");
    }
}

使用JDK动态代理不需要再配置文件中进行配置,所以现在直接进行测试,但是测试的时候不能使用单测,而是使用main方法进行测试

package demo15;

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

/**
 * Created by mycom on 2018/3/8.
 */
public class Test {
    public static void main(String[] args) {
        //首先创建一个接口的实现类
        final SomeServiceImpl service=new SomeServiceImpl();
        //在调用方法之前想使用动态代理记录一下日志,生成动态代理,返回的是接口
        ISomeService proxyInstance =(ISomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
                service.getClass().getInterfaces(), new InvocationHandler() {
                    /**
                     *
                     * @param proxy  代理对象
                     * @param method  目标类型的方法
                     * @param args  方法的参数
                     * @return
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //在这里记录一下日志
                        System.out.println("before=====");
                        //调用method 的
                        method.invoke(service,args);//相当于执行目标类型的方法
                        System.out.println("after=======");
                        return null;
                    }
                });

        //调用动态代理中的方法中的方法
        proxyInstance.doSome();
    }
}

运行的结果如下

这说明运行时先执行了invoke方法,再执行接口中doSome的方法,实验成功!

使用CGLIB动态代理实现上述中的运行结果,如何实现呢?

这时就不用再创建接口了,(在这里我就使用上面的SomeServiceImpl这个类了,这个类中不用做改动),我直接进行测试了,测试还和上面一样,使用main方法测试,不用配置文件

package demo09;

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

import java.lang.reflect.Method;

/**
 * Created by mycom on 2018/3/8.
 */
public class Test {
    public static void main(String[] args) {
        final SomeServiceImpl service=new SomeServiceImpl();
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(service.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            /**
             *
             * @param o 代理对象
             * @param method 目标类型的方法
             * @param objects 目标方法的参数
             * @param methodProxy 代理类的方法   是一个新的参数
             * @return
             * @throws Throwable
             */
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("before=====");
                methodProxy.invoke(service,objects);
                System.out.println("after=====");
                return null;
            }
        });
        SomeServiceImpl proxy =(SomeServiceImpl) enhancer.create();
        proxy.doSome();
    }
}

运行结果和上面的一样,这就是两种方法实现动态代理!

原文地址:https://www.cnblogs.com/my-123/p/8531479.html

时间: 2024-10-24 22:50:53

Spring(七)动态代理的相关文章

spring aop 动态代理批量调用方法实例

今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候要批量调用这些同名方法,我觉得这里可以发展成有潜力的代码. 推送比较好做数据,队友们都写好代码,但是有个问题,方法要的值都大致相同,封装的方式不一致,多人开发,有的封装对象里面,有的直接使用 Map.get(),唉,一千个人一千个哈姆雷特嘛,只好利用反射和动态代理节省自己的代码量,而且这种方式练练手

WebServcie结合Spring结合动态代理进行抽象封装以及性能优化

webService抽象客户端封装.动态代理提升使用性能 1. 什么是webService webService就是在web上提供非相关系统与系统之间进行数据交互的一种服务.通过实现定义好的wsdl借口配置文件,进行约定以及调用. 在企业的内部系统中很常见,尤其是比较大型的企业,有数十种内部使用的系统,之间的通信基本上都是使用webService. 通俗点说就是:你要调用别人的服务,你就通过wsdl生成客户端代码,方便进行直接调用. 你需要被别人调用,你就通过wsdl生成服务端代码,方便对方系统

详解 spring AOP 动态代理

通过例子查看,首先建立一个实现动态代理的接口Interface1.java,代码如下: package my.spring.fuck.aoptest; public interface Interface1 { public void say_hello(); } 很简单的一个接口,然后定义一个这个接口的实现类MyImple.java,代码: package my.spring.fuck.aoptest; public class MyImple implements Interface1{ @

Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只能为接口创建代理实例. 如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生成被代理接口的新的匿名实现类. JDK动态代理具体实现原理: 通过实现InvocationHandlet接口创建自己的调用处理器: 通过为Proxy类指定ClassLoader对象和一组in

Spring AOP动态代理

出现org.springframework.aop.framework.ProxyFactoryBean cannot be cast to 错误 在类型转换的时候, 调用getObject()方法,再对ProxyFactoryBean进行转换 xml文件 <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy><!--使用cglib动态代理--> <be

Spring之动态代理两种实现

基于jdk实现的动态代理 1 package com.proxy.daili; 2 3 import com.proxy.daili.service.IModelMath; 4 5 import java.lang.reflect.InvocationHandler; 6 import java.lang.reflect.Method; 7 import java.lang.reflect.Proxy; 8 import java.util.Arrays; 9 10 /** 11 * 动态代理模

Spring AOP详解 、 JDK动态代理、CGLib动态代理

AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中. 一.AOP术语 1.连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化之前.类初始化之后.类某个方法调用前.调用后等:一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就成为“连接点”,Spring仅支持方法的连接点,即

Spring 容器AOP的实现原理——动态代理

参考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from极客学院) 一.介绍 Spring的动态代理有两种:一是JDK的动态代理:另一个是cglib动态代理(通过修改字节码来实现代理). 今天主要讨论JDK动态代理的方式. JDK的代理方式主要就是通过反射跟动态编译来实现的,主要搭配InvocationHandler和Proxy来实现,下面的例子中使用了两层代理(即代理上加了一层代理). 二.

菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理

之前写了一篇关于IOC的博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽歪歪了,至于有多爽,各位自己脑补吧:而AOP呢,它实现的就是容器的另一大好处了,就是可以让容器中的对象都享有容器中的公共服务.那么容器是怎么做到的呢?它怎么就能让在它里面的对象自动拥有它

【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中. 一.AOP术语 1.连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化之前.类初始化之后.类某个方法调用前.调用后等:一个类