静态代理
需要事先定义好接口或者父类,并且需要有实现好接口或者父类的被代理的对象和代理对象
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService{
@Override
public void save() {
System.out.println("user save");
}
}
public class UserServiceProxy implements UserService{
private UserService userService = new UserServiceImpl();
@Override
public void save() {
userService.save();
}
}
public class Test {
public static void main(String[] args) {
// 静态代理
UserServiceProxy u = new UserServiceProxy();
u.save();
}
}
JDK实现代理
代理对象不需要实现接口,但是目标对象需要实现接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理开始");
Object returnValue = method.invoke(target, args);
System.out.println("动态代理结束");
return returnValue;
}
});
}
}
public class Test {
public static void main(String[] args) {
// 静态代理
UserServiceProxy u = new UserServiceProxy();
u.save();
// 动态代理
UserService userService = new UserServiceImpl();
UserService us = (UserService) new ProxyFactory(userService).getProxyInstance();
us.save();
}
}
cglib代理
有时候目标对象并没有实现任何接口,只是一个单独的对象,这个时候可以以目标对象为父类的方式来实现代理,不能对 final类进行继承
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 ProxyFactory2 implements MethodInterceptor{
private Object target;
public ProxyFactory2(Object target) {
this.target = target;
}
public Object getProxyInstance() {
Enhancer en = new Enhancer();
en.setSuperclass(target.getClass());
en.setCallback(this);
return en.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("cglib开始");
Object returnValue = arg1.invoke(target, arg2);
System.out.println("cglib结束");
return returnValue;
}
}
public class Test {
public static void main(String[] args) {
// 静态代理
UserServiceProxy u = new UserServiceProxy();
u.save();
// 动态代理
UserService userService = new UserServiceImpl();
UserService us = (UserService) new ProxyFactory(userService).getProxyInstance();
us.save();
// cblib
UserService us2 = (UserService) new ProxyFactory2(userService).getProxyInstance();
us2.save();
}
}
在Spring的AOP编程中:
如果加入容器的目标对象有实现接口,用JDK代理
如果目标对象没有实现接口,用Cglib代理