版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lsf921016/article/details/69219954
代理是实现AOP(Aspect oriented program,面向切面编程)的核心和关键技术。
1.什么是代理(proxy)?
代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类负责为委托类预处理消息,过滤消息并转发消息以及进行消息被委托类执行后的后续处理。为了保持行为的一致性,代理类和委托类通常会实现相同的接口
- 静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,也就是说在程序运行前代理类的.class文件就已经存在。
- 动态代理:在程序运行时运用反射机制动态创建生成。
紫色线代表继承关系,红色线代表调用关系
2. 动态代理
- JVM可以在运行期动态生成类的字节码,该类往往被用作动态代理类。
- JVM生成的动态类必须实现一个或多个接口,所以这种只能用作具有相同接口的目标类的代理。
- CGLIB库可以动态生成一个类的子类,一个类的子类也可作为该类的代理,这个可用来为没有实现接口的类生成动态代理类。
- 代理类可在调用目标方法之前、之后、前后、以及处理目标方法异常的catch块中添加系统功能代码。
3. 创建代理对象
创建代理对象的作用:动态地生成一个类,该类实现了A,B接口,然后创建该类的对象。
需要创建出一个新类,被ClassLoader加载进方法区。
Proxy.newProxyInstance()方法的三大参数:
1. ClassLoad:
2. Class[] interfaces:需要实现的接口们
3. InvocationHandler: 每次调用都会执行invoke()方法内的代码
//参数一
ClassLoader loader=this.getClass().getClassLoader();
//参数二
Class[] interfaces={A.class,B.class};
//参数三
InvocationHandler invocationHandler=new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invocation");
return null;
}
};
//创建一个实现了A接口和B接口的代理对象
Object proxy= Proxy.newProxyInstance(loader,interfaces,invocationHandler);
//强转
A a=(A)proxy;
B b=(B)proxy;
System.out.println(proxy.getClass().getName());
InvocationHandler接口只有一个invoke方法,每次调用代理类的方法,即调用了InvocationHandler对象的invoke方法
invoke方法涉及三个要素:
- 代理对象
- 代理对象调用的方法
- 方法接受的参数
注:Object类的hashCode,equals,toString方法交给invoke,其他的Object类的方法,Proxy有自己的实现。
4.实现一个代理工厂模式
需求:男服务员实现服务员接口,在进行服务员的所有方法时,都被beforeAdvice和AfterAdvice装饰
/**@author
* 用来生成代理对象
* 它需要所有的参数:
* 1.目标对象
* 2.增强内容
*
* 代理工厂使用过程:
*
* 1.创建代理工厂
* 2.设置三个成员变量:
* 目标对象
* 前置增强
* 后置增强
* 3.调用getProxy得到代理对象
* 执行代理对象的方法时:
* 执行BeforeAdvice的before()
* 执行目标对象的目标方法
* 执行AfterAdvice的after()
*/
public class ProxyFactory {
private Object targetObject;//目标对象
private BeforeAdvice beforeAdvice;
private AfterAdvice afterAdvice;
//用来生成代理对象
public Object getProxy(){
//给出创建Proxy对象的三大参数
ClassLoader classLoader=this.getClass().getClassLoader();
Class[] interfaces=targetObject.getClass().getInterfaces();
InvocationHandler h=new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用代理对象的方法时会执行这里的内容
if (beforeAdvice!=null){
beforeAdvice.before();
}
Object res=method.invoke(targetObject,args);
if (afterAdvice!=null)
afterAdvice.after();
return res;
}
};
Object proxyObject= Proxy.newProxyInstance(classLoader,interfaces,h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
public interface Waiter {
public void serve();
public void washing();
public void cashing();
}
public class ManWaiter implements Waiter {
@Override
public void serve() {
System.out.println("serving");
}
@Override
public void washing() {
System.out.println("washing dishes");
}
@Override
public void cashing() {
System.out.println("cashing money");
}
}
public interface BeforeAdvice {
public void before();
}
public interface AfterAdvice {
public void after();
}
运行:
public class demo {
public static void main(String[] args) {
ProxyFactory factory=new ProxyFactory();
factory.setTargetObject(new ManWaiter());
factory.setBeforeAdvice(new BeforeAdvice() {
@Override
public void before() {
System.out.println("this is before .........");
}
});
factory.setAfterAdvice(new AfterAdvice() {
@Override
public void after() {
System.out.println("this is after");
}
});
Waiter waiter= (Waiter) factory.getProxy();
waiter.serve();
waiter.washing();
waiter.cashing();
}
}
输出:
this is before ………
serving
this is after
this is before ………
washing dishes
this is after
this is before ………
cashing money
this is after