一 使用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性能高。