代理proxy
总结代理类作用:为原始目标类(目标对象)增加额外的功能。
public interface UserService {
void login();
void register();
}
public class UserServiceImpl implements UserService{
@Override
public void login() {
System.out.println("login()....");
}
@Override
public void register() {
System.out.println("re");
}
}
此时需求为login和register方法增加log日志
名词解释
目标类:我们称UserServiceImpl这样的类为原始类或者目标类
额外功能:即增加的log输出这功能,额外功能不影响原始目标类功能,可有可无
静态代理
通过静态代理实现上述需求,静态代理通过实现原始类接口,保证与原始类有同样的方法,代理对象内部拥有原始类。
public class UserServiceProxy implements UserService {
UserServiceImpl userService = new UserServiceImpl();
@Override
public void login() {
System.out.println("-------log-------------");
userService.login();
}
@Override
public void register() {
System.out.println("-------log-------------");
userService.register();
}
}
缺点:
- 当有新的类需要代理时,需要增加代理类,导致代理类逐渐增多,不利于代码维护;
- 代码耦合度过高
动态代理
动态代理底层原理是通过字节码技术在JVM中生成代理类,即没有生成.class文件,生命周期与JVM保持一致,当JVM关闭后,代理类消失;
由此可以动态代理类好处:利于代码维护
常见的动态代理有JDK和cglib
JDK proxy
JDK代理主要通过Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h )方法创建,返回的即是目标类的代理对象
方法参数
ClassLoader loader:类加载器,借用
interfaces:目标类接口
InvocationHandler :接口,即上面提到的额外功能
public class JdkProxy {
public static void main(String[] args) {
//1、目标类
UserService userService = new UserServiceImpl();
//2、额外功能
InvocationHandler handler = new InvocationHandler() {
/**
*
* @param proxy 代理类,基本不用
* @param method 目标类被调用的方法
* @param args 目标类被调用方法参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret;
System.out.println("----log---------------------------");
ret = method.invoke(userService, args);
return ret;
}
};
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), userService.getClass().getInterfaces(), handler);
userServiceProxy.login();
}
}
JDK动态代理底层原理也是通过字节码技术实现目标类接口,所以JDK代理是必须要有接口;
总结JDK动态代理开发流程
1、创建目标类对象
2、实现额外功能 InvocationHandler接口
3、Proxy.newProxyInstance(...)创建代理对象
Cglib proxy
cglib底层原理是通过类继承实现, cglibProxy extends 目标类生成代理对象,拥有目标类所有方法。
public class UserServiceCglibProxy {
public static void main(String[] args) {
OrderService orderService = new OrderService();
MethodInterceptor interceptor = new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("-------------log-------------------");
return method.invoke(orderService,args);
}
};
Enhancer enhancer = new Enhancer();
//设置类加载器
enhancer.setClassLoader(UserServiceCglibProxy.class.getClassLoader());
//设置目标类
enhancer.setSuperclass(orderService.getClass());
//设置额外功能
enhancer.setCallback(interceptor);
//创建代理对象
OrderService orderProxy = (OrderService) enhancer.create();
orderProxy.show();
}
}
总结Cglib开发流程
1、创建目标类对象
2、实现MethodInterceptor接口提供额外功能
3、Enhancer对象设置类加载器,目标类,额外功能
4、创建代理对象