Chapter 5, CGLib dynamic proxies

Copyright: Reprinted please note the name of the source https://blog.csdn.net/meism5/article/details/90781518

In order to solve the JDK dynamic proxy agent can not issue class does not implement interface can be used to achieve CGLib dynamic proxy.

CGLib (Code Generator Library) is a powerful, high-performance code generation libraries. The bottom of the ASM using (a dapper bytecode manipulation frame) is operated to generate a new class bytecode.

For more information about the CGLib

 

Below we realized based CGLib

  • Print each request takes from start to finish
  • Check whether the current user to log certain requests

1, add the maven pom file of dependence on CGLib

<dependency>
	<groupId>cglib</groupId>
	<artifactId>cglib</artifactId>
	<version>3.2.10</version>
</dependency>

2, dynamic proxy implementation based cglib

package constxiong.cxproxy.chapter5.proxy;

import java.lang.reflect.Method;
import java.util.Random;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 基于 cglib 实现的动态代理 
 * @author ConstXiong
 * @date 2019-06-04 16:26:13
 */
public class CglibProxy implements MethodInterceptor {
	
	//获取用户信息的方法名
	private static final String METHOD_GET_USERINFO = "getUserInfo";
	
	private CglibProxy() {
	}
	
	//单例模式获取代理类对象
	private static CglibProxy proxy = new CglibProxy();
	
	public static CglibProxy getInstance() {
		return proxy;
	}
	
	
	/**
	 * 获取被代理后的目标类
	 * @param clazz 目标类
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> clazz) {
		return (T) Enhancer.create(clazz, this);
	}
	
	/**
	 * 代理执行目标类方法
	 */
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		Object result = null;
		long start = System.currentTimeMillis();//计时开始
		if (METHOD_GET_USERINFO.equals(method.getName())) {//获取用户信息方法
			if (checkIsLogined()) {//校验是否登录
				result = proxy.invokeSuper(obj, args);//目标类的方法调用,与结果获取
			}
		} else {//非获取用户信息方法,不校验是否登录
			result = proxy.invokeSuper(obj, args);//目标类的方法调用,与结果获取
		}
		long end = System.currentTimeMillis();//计时结束
		System.out.println("耗时:" + (end - start) + "毫秒");//打印耗时
		return result;
	}

	/**
	 * 模拟  当前用户是否登录
	 */
	private boolean checkIsLogined() {
		Random r = new Random();
		int i = r.nextInt(10);
		if (i % 2 == 0) {
			System.out.println("已登录");
			return true;
		}
		System.out.println("未登录");
		return false;
	}
	
}

3, the service interface remains the same

package constxiong.cxproxy.chapter5.service;

import java.util.HashMap;
import java.util.Map;

/**
 * 服务接口实现
 * @author ConstXiong
 * @date 2019-05-29 11:02:15
 */
public class ServiceImpl implements Service {

	/**
	 * 登录
	 */
	@Override
	public boolean login(String username, String password) {
		simulateDaOperation(100);
		System.out.println("用户名:" + username + ", 密码:" + password + "  登录成功");
		return true;
	}

	/**
	 * 根据用户名获取用户信息
	 */
	@Override
	public Map<String, Object> getUserInfo(String username) {
		Map<String, Object> userInfo = new HashMap<String, Object>();
		simulateDaOperation(150);
		userInfo.put("username", username);
		userInfo.put("sex", "男");
		userInfo.put("age", 18);
		System.out.println("用户名:" + username + ", 获取用户信息:" + userInfo);
		return userInfo;
	}
	
	/**
	 * 模拟数据库操作,休眠
	 * @param millis 毫秒数
	 */
	private void simulateDaOperation(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

4, the test class

package constxiong.cxproxy.chapter5;

import constxiong.cxproxy.chapter5.proxy.CglibProxy;
import constxiong.cxproxy.chapter5.service.Service;
import constxiong.cxproxy.chapter5.service.ServiceImpl;

/**
 * 测试类
 * @author ConstXiong
 * @date 2019-06-04 16:16:30
 */
public class Test {

	public static void main(String[] args) {
		Service service = CglibProxy.getInstance().getProxy(ServiceImpl.class);
		service.login("ConstXiong", "123456");
		service.getUserInfo("ConstXiong");
	}
	
}

 The results of printing with in  Chapter 2, do not use a proxy  consistent results. 

 

PS:

JDK dynamic proxy with the version upgrade, enhance display performance. Starting from JDK 1.8, performance is better than the dynamic proxy CGLib.

 

Complete source: https://github.com/ConstXiong/xtools     cxproxy project chapter5

 

Guess you like

Origin blog.csdn.net/meism5/article/details/90781518