1. 程式人生 > >使用JDK和Cglib兩種方式動態代理

使用JDK和Cglib兩種方式動態代理

一 使用JDK動態代理

這種方式,只能對介面進行動態代理,有一定的侷限性;

介面:

package org.spring.test2;

import java.util.Map;

public interface UserService {
	void insert(Map<String,Object> param);
}


介面實現類:

package org.spring.test2;

import java.util.Map;

public class UserServiceImpl implements UserService{

	@Override
	public void insert(Map<String, Object> param) {
		System.out.println("in insert");
	}

}


生成代理的類:

package org.spring.test2;

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

public class UserServiceInvocationHandler implements InvocationHandler{
	private UserService userService;
	
	public UserServiceInvocationHandler(UserService userService){
		this.userService=userService;
	}
	

	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		System.out.println("前置增強!");
		Object invoke = arg1.invoke(userService, arg2);
		System.out.println("後置增強!");
		return invoke;
	}

}


測試類:

package org.spring.test2;

import java.lang.reflect.Proxy;

public class Test {

	public static void main(String[] args) {
		UserService us=new UserServiceImpl();
		UserService usp = (UserService) Proxy.newProxyInstance(us.getClass().getClassLoader(), 
																us.getClass().getInterfaces(), 
																new UserServiceInvocationHandler(us));
		usp.insert(null);
	}

}


二 使用Cglib動態代理

引入包:

<!-- cglib -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.2.5</version>
		</dependency>


目標類:

package org.spring.test3;

import java.util.Map;

public class UserServiceImpl  {
	public void insert(Map<String,Object> param){
		System.out.println("in insert");
	}
}


生成代理的類:

package org.spring.test3;

import java.lang.reflect.Method;

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


public class CglibProxy implements MethodInterceptor{
	private Enhancer enhancer=new Enhancer();
	
	public Object getProxy(Class clazz){
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}
	

	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		
		System.out.println("前置增強");
		Object res = arg3.invokeSuper(arg0, arg2);
		System.out.println("後置增強");
		return res;
	}

}


測試類:

package org.spring.test3;

public class Test {

	public static void main(String[] args) {
		CglibProxy proxy = new CglibProxy();
		UserServiceImpl us = (UserServiceImpl) proxy.getProxy(UserServiceImpl.class);
		us.insert(null);
		
	}

}

說明:cglib生成代理是通過位元組碼生成的子類作為代理類,因此不能對private final方法代理;

比較:

CGLib動態代理建立代理例項速度慢,但是執行速度快;JDK動態代理建立例項速度快,但是執行速度慢。如果例項是單例的,推薦使用CGLib方式動態代理,反之則使用JDK方式進行動態代理。Spring的例項預設是單例,所以這時候使用CGLib效能高。