代理模式,为其他对象提供一种代理以控制对这个对象的访问。
最典型的应用是Spring的AOP。
代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
静态代理的实现
以代理用户Service为例
接口类
public interface UserService {
public void addUser();
}
实现类
public class UserServiceImpl implements UserService {
public void addUser() {
System.out.println("add user...");
}
}
代理类
public class UserProxy implements UserService{
private UserService userService;
public UserProxy(UserService userService) {
this.userService = userService;
}
public void addUser() {
this.before();
userService.addUser();
this.after();
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
测试方法
UserService userService = new UserServiceImpl();
UserProxy proxy = new UserProxy(userService);
proxy.addUser();
使用jdk实现动态代理
代理类改为
public class UserProxy implements InvocationHandler {
private Object target;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
this.before();
result = method.invoke(target, args);
this.after();
return result;
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
测试类
UserProxy proxy = new UserProxy();
UserService userService = (UserService)proxy.bind(new UserServiceImpl());
userService.addUser();
cglib实现动态代理
jdk动态代理必须依赖接口(UserService),用cglib可以解决该问题。cglib的原理是对指定的目标类生成一个子类,因为采用的是继承,所以不能对final修饰的类进行代理。
代理类
public class UserProxy implements MethodInterceptor {
private Object target;
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
// 回调方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
this.before();
proxy.invokeSuper(obj, args);
this.after();
return null;
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
测试代码
UserProxy proxy = new UserProxy();
UserService userService = (UserService)proxy.getInstance(new UserServiceImpl());
userService.addUser();