Java设计模式之JDK动态代理和CGLib动态代理的实现案例

接口设计:

public interface UserService {

    public void getUser();
    
}

接口实现类:

public class UserServiceImpl implements UserService{
    
    public void getUser() {
        System.out.println(1);
    } 
}

代理类:

package com.etc.spring.test;

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

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

import com.etc.spring.service.UserService;
import com.etc.spring.service.impl.UserServiceImpl;

public class UserServiceImpProxy {

    /**
     * java代理模式分为JDK动态代理和CGLib代理、静态代理
     * 代理都是基于接口模式实现的
     * @param userServiceImpl
     * @return
     */
    public static UserService getProxyObject(final UserService userServiceImpl){
        
        //三个参数目标类的类加载器、目标类的接口、InvocationHandler对象
        UserService userService = (UserService)Proxy.newProxyInstance(userServiceImpl.getClass().getClassLoader(), userServiceImpl.getClass().getInterfaces(), new InvocationHandler() {
            //匿名内部类实现
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //可以在调用目标对象的前后,加上自己需要的日志
                System.out.println("记录开始................");
                Object object =  method.invoke(userServiceImpl, args);
                System.out.println("记录结束................");
                return object;
            }
        });
        return userService;
    }
    
    /**
     * cglib需要用到Enhanceer创建增强器
     * cglib是基于继承的方式实现的
     * @param userService
     * @return
     */
    public static UserService getProxyByCGLib(UserService userService){
        
        //创建增强器
        Enhancer enhancer = new Enhancer();
        //设置需要增强类的对象
        enhancer.setSuperclass(UserService.class);
        //调用回调方法
        enhancer.setCallback(new MethodInterceptor() {
            
            //代理对象是目标对象的子类
            //MethodProxy代理之后的对象的方法引用
            public Object intercept(Object object, Method method, Object[] arg2, MethodProxy proxy) throws Throwable {
                
                System.out.println("cglib开始...............");
                UserService userService = (UserService)proxy.invokeSuper(object, arg2);
                System.out.println("cglib结束...............");
                return userService;
            }
        });
        
        //获取增强之后的代理对象
        UserService userService2 = (UserService)enhancer.create();
        return userService2;
    }
}
 

测试类:

@org.junit.Test
    public void test2(){
        
        System.out.println("jdk动态代理测试...........");
        //创建目标对象
        UserService service = new UserServiceImpl();
        //生成代理对象
        UserService proxy = UserServiceImpProxy.getProxyObject(service);
        //调用目标对象方法
        service.getUser();
        //调用代理对象方法
        proxy.getUser();
        System.out.println("cglib动态代理测试..........");
        UserService service2 = new UserServiceImpl();
        UserService cgService = UserServiceImpProxy.getProxyByCGLib(service2);
        service2.getUser();
        cgService.getUser();
    }

输出:

jdk动态代理测试...........
1
记录开始................
1
记录结束................
cglib动态代理测试..........
1
cglib开始...............

=============================

jdk动态代理只能基于接口,cglib比较好用,不一定只基于接口,可以基于继承。spring aop原理就是基于动态代理来实现。有接口就用jdk代理实现,没有接口就用cglib实现。

猜你喜欢

转载自blog.csdn.net/u012373281/article/details/89212589
今日推荐