动态代理和cglib代理

使用动态代理和cglib分别实现对类的代理

  • UserService

package com.example.service;

public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}
  • UserServiceImpl

package com.example.service;

public class UserServiceImpl implements UserService {

    @Override
    public void add() {
        /**
         * 正常工作场景add前需要打开事务,add后需要提交事务
         * 这里我交给动态代理和cglib代理需要怎么操作呢?
         */
        //System.out.println("打开事务");
        System.out.println("新增用户");
        //System.out.println("提交事务");
    }

    @Override
    public void delete() {
        System.out.println("删除用户");
    }

    @Override
    public void update() {
        System.out.println("修改用户");
    }

    @Override
    public void select() {
        System.out.println("查找用户");
    }
}
  • 动态代理

package com.example.proxy;

import com.example.service.UserService;
import com.example.service.UserServiceImpl;

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

//增强的接口这里由本身来实现
//动态代理类

public class UserServiceProxyFactory implements  InvocationHandler{
    //传入代理实例
    private UserService us;

    public UserServiceProxyFactory(UserService us) {
        this.us = us;
    }

    /**
     *     动态代理方法
     */
    //定义一个工厂方法,返回一个UserService代理对象
    public UserService getUserServiceProxy(){
        //生成动态代理 类加载器 活动被加载对象实现的接口 增强的接口
        UserService userProxy =(UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                UserServiceImpl.class.getInterfaces(), this);
        return userProxy;
    }

    /**
     *
     * @param proxy 当前代理对象 UserServiceProxyFactory
     * @param method 当前方法 getUseServiceProxy
     * @param args 当前方法返回的参数 UserService类型的 userProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //返回实例us
        System.out.println("打开事务");
        Object invoke = method.invoke(us,args);
        System.out.println("关闭事务");
        return null;
    }
}
  • cglib代理

package com.example.proxy;

import com.example.service.UserService;
import com.example.service.UserServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

//cglib代理类
public class UserServiceProxyFactory2 implements MethodInterceptor {
    /**
     * cglib代理
     * spring整合了cglib包,cglib包核心类Enhancer
     * cglib继承类实现
     */
    public UserService getUserServiceProxy(){
        Enhancer enhancer = new Enhancer();//帮我们生成代理对象
        enhancer.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
        enhancer.setCallback(this);//代理要做什么,要求得到一个callback接口。交由本身去实现
        UserService us = (UserService) enhancer.create();//创建代理对象
        return us;
    }

    //实现enhancer.setCallback();接口。传来了四个参数。实现其MethodInterceptor方法
    @Override
    public Object intercept(Object obj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
        //打开事务
        System.out.println("打开事务");
        //调用原有方法
        Object returnValue = methodProxy.invokeSuper(obj,arg);
        //提交事务
        System.out.println("提交事务");
        return returnValue;
    }
}
  • 测试

package com.example.proxy;

import com.example.service.UserService;
import com.example.service.UserServiceImpl;
import org.junit.Test;


public class Demo03 {
    @Test
    public void proxyTest() {
        UserService us = new UserServiceImpl();
        UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
        UserService userProxy = factory.getUserServiceProxy();
        //调用增加方法
        userProxy.add();
        //代理对象与被代理对象实现了相同的接口 false
        //动态代理中 代理对象与被代理对象没有没有继承关系,仅是实现了同一个接口
        System.out.println(userProxy instanceof  UserServiceImpl);
    }
    @Test
    public void proxyTest2() {
        UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
        UserService userProxy = factory.getUserServiceProxy();
        //调用增加方法
        userProxy.add();
        //判断代理对象是否属于被代理对象类型
        //cglib代理对象继承了被代理对象 true
        System.out.println(userProxy instanceof  UserServiceImpl);
    }
}

  • 总结

  1. 动态代理(其局限性,被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术)
    Proxy.newProxyInstance(classLoader.Interface[] arr,InvocationMandeler handler)
  2. cglib代理(其优点,作为第三方代理技术,cglib可以对任何类生成代理,代理的原理是对目标对象进行继承代理。但如果目标是被final修饰符修饰,那么该类无法被cglib代理)
    总结,有接口存在时,优先使用动态动态,无接口时用cglib代理。
posted @ 2021-09-07 20:37  LanceYa  阅读(72)  评论(0)    收藏  举报