JDK动态代理

Posted 虫儿aqa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK动态代理相关的知识,希望对你有一定的参考价值。

package com.itheima.a_proxy.a_jdk;

public class MyAspect {
    
    public void before(){
        System.out.println("鸡首");
    }
    
    public void after(){
        System.out.println("牛后");
    }

}

UserService接口

package com.itheima.a_proxy.a_jdk;

public interface UserService {
    
    public void addUser();
    public void updateUser();
    public void deleteUser();

}

 UserServiceImpl实现类

package com.itheima.a_proxy.a_jdk;

public class UserServiceImpl implements UserService {

    @Override
    public void addUser() {
        System.out.println("a_proxy.a_jdk addUser");
    }

    @Override
    public void updateUser() {
        System.out.println("a_proxy.a_jdk updateUser");

    }

    @Override
    public void deleteUser() {

        System.out.println("a_proxy.a_jdk deleteUser");
    }

}

 

 工厂类

package com.itheima.a_proxy.a_jdk;

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

public class MyBeanFactory {
    
    public static UserService createService(){
        //1 目标类
        final UserService userService = new UserServiceImpl();
        //2切面类
        final MyAspect myAspect = new MyAspect();
        /* 3 代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面
         *     Proxy.newProxyInstance
         *         参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。
         *             一般情况:当前类.class.getClassLoader();
         *                     目标类实例.getClass().get...
         *         参数2:Class[] interfaces 代理类需要实现的所有接口
         *             方式1:目标类实例.getClass().getInterfaces()  ;注意:只能获得自己接口,不能获得父元素接口
         *             方式2:new Class[]{UserService.class}   
         *             例如:jdbc 驱动  --> DriverManager  获得接口 Connection
         *         参数3:InvocationHandler  处理类,接口,必须进行实现类,一般采用匿名内部
         *             提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke
         *                 参数31:Object proxy :代理对象
         *                 参数32:Method method : 代理对象当前执行的方法的描述对象(反射)
         *                     执行方法名:method.getName()
         *                     执行方法:method.invoke(对象,实际参数)
         *                 参数33:Object[] args :方法实际参数
         * 
         */
        UserService proxService = (UserService)Proxy.newProxyInstance(
                                MyBeanFactory.class.getClassLoader(), 
                                userService.getClass().getInterfaces(), 
                                new InvocationHandler() {
                                    
                                    @Override
                                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                        
                                        //前执行
                                        myAspect.before();
                                        
                                        //执行目标类的方法
                                        Object obj = method.invoke(userService, args);
                                        
                                        //后执行
                                        myAspect.after();
                                        
                                        return obj;
                                    }
                                });
        
        return proxService;
    }

}

 

 测试类

package com.itheima.a_proxy.a_jdk;

import org.junit.Test;

public class TestJDK {
    
    @Test
    public void demo01(){
        UserService userService = MyBeanFactory.createService();
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

}

 

 

 

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

JDK动态代理CGLIB动态代理

JDK动态代理CGLIB动态代理

(java反射-JDK动态代理)+CGLIB动态代理

JDK动态代理与Cglib动态代理

JDK动态代理与CGLib动态代理

代理模式(静态代理jdk动态代理CGLib动态代理)