java静态代理、动态代理实现
静态代理
1.被代理接口类
2.被代理类
3.代理类
(1)实现被代理接口
(2) 定义一个被代理接口的成员变量
注意: 因为代理类中有被代理接口的成员变量,所以代理类可以相互继承
new TankLogProxy(new TankTimeProxy(new Tank())).move();
静态代理实现
package com.proxy.staticstate;
public class Tank implements Movable {
@Override
public void move() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Tank is move");
}
public static void main(String[] args) {
/**
* 代理嵌套
*/
new TankLogProxy(new TankTimeProxy(new Tank())).move();
}
}
/**
* 计算时间的静态代理
*/
class TankTimeProxy implements Movable {
private Movable movable;
public TankTimeProxy(Movable movable) {
this.movable = movable;
}
@Override
public void move() {
long startTime = System.currentTimeMillis();
movable.move();
long endTime = System.currentTimeMillis();
System.out.println("inovke the method move time: " + (endTime - startTime) / 1000d);
}
}
class TankLogProxy implements Movable {
private Movable movable;
public TankLogProxy(Movable movable) {
this.movable = movable;
}
@Override
public void move() {
System.out.println("before moving");
movable.move();
long endTime = System.currentTimeMillis();
System.out.println("end moving");
}
}
interface Movable {
void move();
}
JDK动态代理
1.JDK动态代理是基于接口
2. 使用Proxy.newProxyInstance生成动态代理
Movable movable = (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(), new Class[]{Movable.class},new TimeHandler(tank));
return movable;
newProxyInstance参数介绍
1.ClassLoader loader: 选择用哪个classLoader来返回的代理对象load到内存
2.Class<?>[] interfaces 应该实现哪些接口
3.InvocationHandler 具体的实现,包含三个参数,proxy就是生成的代理类,method就是被代理的方法,args 就是被代理方法的参数
4. 生成代理类,是通过asm框架实现的
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
如何显示的生成代理类
默认JDK动态生成的代理类,是存在内存中的;
不同的JDK版本,参数可能不同,具体的查看 ProxyGenerator.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
JDK动态代理实例
package com.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Tank implements Movable {
@Override
public void move() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Tank is move");
}
public static Movable tankTimeProxy(final Tank tank){
// //通过二级制字节码分析类的属性和方法
/**
* ClassLoader loader: 选择用哪个classLoader来返回的代理对象load到内存
* Class<?>[] interfaces: 应该实现哪些接口
* InvocationHandler h :
*
* 生成proxy是通过asm生成的
*
*/
//ProxyGenerator 通过指定这个参数,可以让动态代理类生成出来,默认只存在于内存中
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
Movable movable = (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(), new Class[]{Movable.class},new TimeHandler(tank));
return movable;
}
public static void main(String[] args) {
final Tank tank = new Tank();
Movable movable = tankTimeProxy(tank);
movable.move();
}
}
class TimeHandler implements InvocationHandler{
private Movable movable;
public TimeHandler(Movable movable) {
this.movable = movable;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method "+method.getName()+" starting");
Object o = method.invoke(movable,args);
System.out.println("method "+method.getName()+" end");
return o;
}
}
interface Movable {
void move();
}
CGLIB动态代理
1.CGLIB是基于被代理类生成的
2.代理类是被代理类的子类
3.也是通过asm框架生成的代理类
CGLIB动态代理实例
package com.proxy.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class Tank {
public void move() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Tank is move");
}
public static void main(String[] args) {
/**
* cglib生成的是被代理类的子类
*/
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Tank.class);
enhancer.setCallback(new LogMethodInterceptor());
Tank tank = (Tank)enhancer.create();
tank.move();
}
}
class LogMethodInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before method "+ method.getName());
Object invoke =methodProxy.invokeSuper(o,objects);
System.out.println("after method "+ method.getName());
return invoke;
}
}
Spring AOP
spring aop也是通过asm框架实现的