使用JDK和Cglib兩種方式動態代理
阿新 • • 發佈:2019-01-03
一 使用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效能高。