Spring AOP基础之JDK动态代理

                         JDK动态代理

  Jdk动态代理是装饰模式的一个典型用例,关于装饰模式这里不多解释,直接说重点吧.jdk动态代理实际上就是代替继承方案,在不破坏原始类的原则下,在运行期间为某个类动态注入一些新的方法。java.lang.reflect.Proxy提供了生成代理类的接口。进入源代码,我们可以看见关于Proxy的详细说明这里截取一些关键的部分:

/**
 * {@code Proxy} provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
 *(Proxy提供了提供了一系列生成动态代理类或实例静态的方法,它是所有动态代理类的超类)
 *    目标类:就是你要代理的对象
 *    代理类:代理目标类执行动作的类
 *
 * <p>To create a proxy for some interface {@code Foo}:
 *(给目标类添加一些方法(接口)生成代理类的方法:)
 * <pre>
 *    //获取自定义处理类对象
 *     InvocationHandler handler = new MyInvocationHandler(...);
 *    //获取代理类字节码对象
 *     Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
 *    //生成代理类对象实例
 *     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
 *                     newInstance(handler);
 * </pre>
 * or more simply:(也可以用如下更简单的方式:)
 * <pre>
 *    //这里使用了匿名内部类的方式,直接将处理逻辑推迟到用户具体定义使用的时候,具有极大的灵活性
 *
 *    //Foo.class.getClassLoader()获取类加载器,以便将代理类注册到内存,实际上这里是指虚拟机
 *      //new Class<?>[] { Foo.class } 获取目标类所有的方法(接口)
 *    //handler 自定义的处理逻辑,也就是说你拿到方法后要干什么
 * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                          new Class&lt;?&gt;[] { Foo.class },
 *                                          handler);
 * </pre>

官方已经详细介绍了这个接口的使用方法,同时也对其中的原理做了阐述,这里就直接上实例来说说具体用法吧,jdk动态代理的实现原理 这种鬼东西至少也要在你会用的基础上再研究吧,等你会用了,自

己直接看源码去,以你的智商那还不是小ks。

  • 目标类接口设计 
  • package com.heima_aop;
    
    public interface UserService {
        public void addUser();
        public void updateUser();
        public void deleteUser();
    }

  • 目标类接口实现
  • package com.heima_aop;
    
    public class UserServiceImpl implements UserService {
    
        @Override
        public void addUser() {
            System.out.println("addUser");
        }
    
        @Override
        public void updateUser() {
            System.out.println("updateUser");
        }
    
        @Override
        public void deleteUser() {
            System.out.println("deleteUser");
        }
    
    }

  • 代理类设计
  • package com.heima_aop;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Proxy;
    
    public class ProxyFactoryBean {
    
        public static UserService createUserService() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
            // 目标类
            final UserService service = new UserServiceImpl();
            // 切面类
            final MyAspect aspect = new MyAspect();
    
            //处理类
            MyInvocationHandler handler = new MyInvocationHandler(service);
    
            /**
             * 生成代理对象字节码
             */
            Class<?> proxyClass = Proxy.getProxyClass(ProxyFactoryBean.class.getClassLoader(), new Class[]{UserService.class});
    
            /**
             * 使用反射调用代理类对象的构造函数,通过InvocationHandler接口进行规范,InvocationHandler的接口实现类对象告知其具体处理方式
             */
            UserService proxy = (UserService) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
    
            /*
             * 方法二:
             * UserService proxy = (UserService) Proxy.newProxyInstance(
                    ProxyFactoryBean.class.getClassLoader(),
                    new Class[] { UserService.class },
                     new MyInvocationHandler(service));
    
                方法三:(使用匿名内部类,官方推荐)
                    UserService proxy =(UserService) Proxy.newProxyInstance(
                    ProxyFactoryBean.class.getClassLoader(),
                    new Class[] { UserService.class },InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method,
                                Object[] args) throws Throwable {
                            aspect.Before();
                            Object obj = method.invoke(service, args);
                            aspect.After();
                            return obj;
                        }
                    });
                    */
            return proxy;
        }
    }

  • 测试
  • package com.heima_aop;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Testdemo {
        @Test
        public void test_jdk(){
            String xmlpath = "com/heima_aop/bean.xml";
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlpath);
            UserService service = (UserService) applicationContext.getBean("Userservice");
            service.addUser();
            service.deleteUser();
            /*System.out.println(service);*/
        }
    }

详细项目下载地址:

时间: 2024-10-07 06:32:50

Spring AOP基础之JDK动态代理的相关文章

AOP学习心得&amp;jdk动态代理与cglib比较

什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合.当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力.也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系.例如日志功能.日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无

细说Spring——AOP详解(动态代理实现AOP)

前言 嗯,我应该是有一段实现没有写过博客了,在写完了细说Spring——AOP详解(AOP概览)之后,我发现我不知道该怎么写AOP这一部分,所以就把写博客这件事给放下了,但是这件事情又不想就这么放弃,所以今天我仔细思考了一下,决定还是要克服困难,我仔细的想了一下怎么讲解AOP实现这一部分,然后我决定由浅入深的讲解动态代理,然后用动态代理实现一个简单的AOP,感觉这样能够让人对AOP的原理有一个比较深刻的认识,希望能帮到大家.而且最近学习又组建了ACM比赛的队伍,虽然已经要大三了,按理来说应该一心

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

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

CgLib动态代理学习【Spring AOP基础之一】

如果不了解JDK中proxy动态代理机制的可以先查看上篇文章的内容:Java动态代理学习[Spring AOP基础之一] 由于Java动态代理Proxy.newProxyInstance()的时候会发现其参数类型是ClassLoader classLoader, Class<?>[] interface, InvocationHandler handler, 只支持根据接口实现代理类,如果所有代码都是自己掌控,当然没有问题.所有的业务逻辑均抽象出接口,然后所有的业务类实现接口,这样所有的业务类

[Java]Spring AOP基础知识-动态代理

Spring AOP使用动态代理技术在运行期织入增强的代码,为了揭示Spring AOP底层的工作机理,有必要对涉及到的Java知识进行学习.Spring AOP使用了两种代理机制:一种是基于JDK的动态代理:另一种是基于CGLib的动态代理.之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理. 带有横切逻辑的实例 我们通过具体化代码实现上一节所介绍例子的性能监视横切逻辑,并通过动态代理技术对此进行改造.在调用每一个目标类方法时启动方法的性能监视,在目标类方法调

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

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

重温Spring之旅5——AOP代理对象、JDK动态代理、使用cglib生产代理

AOP--代理对象 代理模式:代理模式的英文叫做Proxy或Surrogate,中文都可译为"代理",所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题. 代理主题(Proxy)角色:代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象:

jdk动态代理与cglib代理、spring aop代理实现原理解析

原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 动态代理实现主要有2种形式,主要分为: 1.jdk动态代理: 1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下) 2)实现方式: 1. 通过实现Invocati

AOP、静态代理、JDK动态代理、CGLIB动态代理、Spring实现AOP、IOC+AOP

一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: 1 package com.zhangguo.Spring041.aop01; 2 3 public class Math { 4 //加 5 public int add(int n1,int n2){ 6 int result=n1+n2; 7 System.out.println(n1+"+"+n2+"="+result); 8 return result; 9 } 1