Spring AOP基础之JDK动态代理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>
View Code

 

 

 

 

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

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

 

  • 目标类接口设计 
  • 技术分享
    package com.heima_aop;
    
    public interface UserService {
        public void addUser();
        public void updateUser();
        public void deleteUser();
    }
    View Code
  • 目标类接口实现
  • 技术分享
    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");
        }
    
    }
    View Code
  • 代理类设计
  • 技术分享
    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;
        }
    }
    View Code
  • 测试
  • 技术分享
    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);*/
        } 
    }
    View Code

     

   详细项目下载地址:

 

 

 

 

 

 

以上是关于Spring AOP基础之JDK动态代理的主要内容,如果未能解决你的问题,请参考以下文章

Spring的AOP总结

Spring之AOP理解及使用

Spring_AOP的实现机制-动态代理

Spring读源码系列之AOP--06---AopProxy===>spring使用jdk和cglib生成代理对象的终极奥义

Spring中AOP技术基础——静态代理动态代理(JDK动态代理)CGLIB代理

Spring中AOP技术基础——静态代理动态代理(JDK动态代理)CGLIB代理