基于子类的动态代理(代理普通的java类)
TODO 动态代理
特点:字节码随用随创建 随用随加载
作用:是在不修改源码的基础上增强
分类:
基于接口的动态代理
基于子类的动态代理
基于子类的动态代理:
涉及的类:Enhancer
提供者 :第三方cglib库
如何创建代理对象:
使用Enhancer类中的create方法
创建代理对象的要求:
被代理的类不能是最终类
create方法的参数:
Class:字节码
它用于指定被代理对象的字节码
Callback:用于提供增强的代码
它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
此接口的实现类都是谁用谁写。
我们一般写的都是该接口的子接口实现类:MethodInterceptor
<!--基于子类的动态代理--> 依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
public class Producer_Son {
public void salesProduct(float money) {
System.out.println("销售产品,并且拿到钱 "+money);
}
public void afterSalesService(float money) {
System.out.println("提供服务,并且拿到钱 "+money);
}
}
public class Client {
public static void main(String[] args) {
// 加载到常量池
final Producer_Son producer =new Producer_Son();
Producer_Son o = (Producer_Son) Enhancer.create(producer.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//1.提供增强的方法
Object returnValue = null;
//2.获取方法执行的参数
Float money = (Float) args[0];
//3.判断当前方法是不是销售
if ("salesProduct".equals(method.getName()))
returnValue = method.invoke(producer, money * 0.8f);
System.out.println(returnValue);
return returnValue;
}
});
o.salesProduct(1000f);
}
}
基于接口的动态代理
TODO 动态代理
特点:字节码随用随创建 随用随加载
作用:是在不修改源码的基础上增强
分类:
基于接口的动态代理
基于子类的动态代理(代理普通的java类)
基于接口的动态代理;
涉及的类:proxy
提供者:JDK官方
如何创建代理对象:
使用Proxy类中的 newProxyInstance 方法
创建代理对象的要求:
被代理类最少实现一个接口 如果没有则不能使用
newProxyInstance 方法的参数:
ClassLoader loader :类加载器
它是用于加载代理对象字节码的 和被代理对象使用相同的类加载器
Class<?>[] interfaces: 字节码数组
它是用于代理对象[接口]和被代理对象[一个类]有相同方法
InvocationHandler:用于提供增强的代码
他是让我们如何写代理。 我们一般都是写一个该接口的实现类 ;通常情况下是匿名内部类 但不是必须的
此接口的实现类都是谁用谁写
Producer
/*
生产者
*/
public interface Producer {
/*
销售产品
*/
void salesProduct(float money);
/*
售后服务
*/
void afterSalesService(float money);
}
Agency
/*
经销商 提供 销售 售后服务
*/
public class Agency implements Producer{
@Override
public void salesProduct(float money) {
System.out.println("销售产品,并且拿到钱 "+money);
}
@Override
public void afterSalesService(float money) {
System.out.println("提供服务,并且拿到钱 "+money);
}
}
Client
/*
动态代理
*/
public class Client {
public static void main(String[] args) {
// 加载到常量池 (匿名内部类)
final Agency agency = new Agency();
Producer proxyInstance = (Producer) Proxy.newProxyInstance(agency.getClass().getClassLoader(), agency.getClass().getInterfaces(), new InvocationHandler() {
/***
* 作用:执行被代理对象的任何接口方法都会经过该方法
* @param proxy 代理对象的引用
* @param method 当前执行的方法
* @param args 当前执行方法所需要的参数
* @return 和被代理对象方法相同的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 提供增强方法
Object returnValue = null;
Float money = (Float) args[0];
if ("salesProduct".equals(method.getName()))
returnValue = method.invoke(agency, money * 0.8f);
System.out.println(returnValue);
return returnValue;
}
});
proxyInstance.salesProduct(10000f);
}
}