23种设计模式——代理模式

相信大家都知道,有23种代理模式,其中用得比较多的或者是面试中估计问的最多的就是动态代理,但是我们知道,动态代理,静态代理都只是23种设计模式中的代理模式。好了,话不多说,直接上干货。

 

代理模式

   1、动态代理

       先创建接口:

       

/**
 * 功能描述
 *
 * @author yaoqihui
 * @version 2021/7/4
 * @see [相关类/方法]
 * @since [malan-rabbitmq]
 */
public interface UserService {
    void saveUser();
}

      写一个类,实现接口:

import com.sailmalan.malan.service.UserService;
import lombok.extern.slf4j.Slf4j;

/**
 * 功能描述
 *
 * @author yaoqihui
 * @version 2021/7/4
 * @see [相关类/方法]
 * @since [malan-rabbitmq]
 */
@Slf4j
public class UserServiceImpl implements UserService {
    @Override
    public void saveUser() {
        log.info("动态代理调用");
    }
}

 

 创建代理类(可以重复利用)


import lombok.extern.slf4j.Slf4j;

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

/**
* 动态代理类
*
* @author yaoqihui
* @version 2021/7/4
* @see [相关类/方法]
* @since [malan-rabbitmq]
*/
@Slf4j
public class InvocationHandlerImpl implements InvocationHandler {
private Object target;

public InvocationHandlerImpl(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method.invoke()方法,真正动态代理的地方,利用的是java的反射,大伙也可以看到包:java.lang.reflect.Method
return method.invoke(target, args);
}
}

 

动态代理测试类:

import com.sailmalan.malan.service.UserService;
import com.sailmalan.malan.service.impl.UserServiceImpl;

import java.lang.reflect.Proxy;

/**
 * 功能描述:生成UserService,供调用---》类似于我们使用springBoot的注解,得到一个userService接口
@Autowired
private UserService userService; * *
@author yaoqihui * @version 2021/7/4 * @see [相关类/方法] * @since [malan-rabbitmq] */
public class TestInvocationHandler {
public static void main(String[] args) {
/************************类似于达到效果的注解:
* @Autowired
* private UserService userService;
* 开始代码**************************/
UserService userService = new UserServiceImpl();
InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl(userService);
ClassLoader loader = userService.getClass().getClassLoader();
Class<?>[] interfaces = userService.getClass().getInterfaces();
UserService newProxyInstance = (UserService) Proxy.newProxyInstance(loader, interfaces, invocationHandler);
/************************结束代码**************************/
newProxyInstance.saveUser();
}
}

 

2、CGLIB静态代理

  • CGLIB动态代理和jdk代理一样,使用反射完成代理,不同的是他可以直接代理类(jdk动态代理不行,他必须目标业务类必须实现接口),CGLIB动态代理底层使用字节码技术,CGLIB动态代理不能对 final类进行继承。(CGLIB动态代理需要导入jar包)

 

    //接口
    public interface UserDao {
        void save();
    }

 

//接口实现类
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("保存数据方法");
    }
}

 

代理类:

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

//代理主要类
public class CglibProxy implements MethodInterceptor {
    private Object targetObject;
    // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
    public Object getInstance(Object target) {
        // 设置需要创建子类的类
        this.targetObject = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    //代理实际方法
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开启事物");
        Object result = proxy.invoke(targetObject, args);
        System.out.println("关闭事物");
        // 返回代理对象
        return result;
    }
}

 

测试:

//测试CGLIB动态代理
public class Test {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDaoImpl());
        userDao.save();
    }
}

 

 

2、静态代理代码演示

 创建UserDao类:

    //接口类
    public class UserDao{
        public void save() {
            System.out.println("保存数据方法");
        }
    }

 

添加代理类

//代理类
public class UserDaoProxy extends UserDao {
    private UserDao userDao;
   //此处是构造器注入
    public UserDaoProxy(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save() {
        System.out.println("开启事物...");
        userDao.save();
        System.out.println("关闭事物...");
    }

}

下面测试静态代理的类:

//添加完静态代理的测试类
public class Test{
    public static void main(String[] args) {
        UserDao userDao = new UserDao();
        UserDaoProxy userDaoProxy = new UserDaoProxy(userDao);
        userDaoProxy.save();
    }
}

posted @ 2021-07-30 18:05  QH.Thomas  阅读(86)  评论(0编辑  收藏  举报