spring 的AOP 实现 可以使用jdk的动态代理,也可以使用cglib的动态代理 先说下两者区别:
静态代理:代理之前就已经知道了代理者和被代理者
动态代理:代理之前并不清楚,在运行时使用反射机制动态生成代理类的字节码 无需我们手动编写它的源代码
jdk动态代理:java.lang.reflect 包中的Proxy类,InvocationHandler 接口提供了生成动态代理类的能力。它必须有被代理对象的接口和实现类,ciglib不需要接口,简单的说 jkd动态代理针对接口,而cglib动态代理针对的是类 比JDK快,但加载cglib的时间比jdk反射的时间长,开发的过程中,如果是反复动态生成新的代理类推荐用 JDK 自身的反射,反之用 cglib。
spring AOP的实现 既可以编写接口使用jdk动态代理实现,也可以使用cglib来进行实现
对于hibernate使用cglib延迟加载,在load()的时候,cglib会生成一个数据库实体类的代理类,此代理类开始的时候里面的属性值是null,只有当真正请求数据,如user.getName()的时候,这个代理类就会去数据库里查询出具体的值(通过cglib的回调机制),然后加载到代理类对应的属性中,最后返回给给调用者。
/**
*使用类
*/
public class MyClass {
public void method() {
System.out.println("MyClass.method()");
}
public void method2() {
System.out.println("MyClass.method2()");
}
}
/**
*使用代理
*/
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//在这代理了
enhancer.setSuperclass(MyClass.class);
enhancer.setCallback( new MethodInterceptorImpl() );
// 创造 代理 (动态扩展了MyClass类)
MyClass my = (MyClass)enhancer.create();
my.method();
}
private static class MethodInterceptorImpl implements MethodInterceptor {
public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println(method);
proxy.invokeSuper(obj, args);
return null;
}
}
}
/**
*添加方法过滤
*/
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
public class Main2 {
public static void main(String[] args) {
Callback[] callbacks =
new Callback[] { new MethodInterceptorImpl(), NoOp.INSTANCE };
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyClass.class);
enhancer.setCallbacks( callbacks );
//添加 方法过滤器 返回1为不运行 2 为运行
enhancer.setCallbackFilter( new CallbackFilterImpl() );
MyClass my = (MyClass)enhancer.create();
my.method();
my.method2();
}
private static class CallbackFilterImpl implements CallbackFilter {
public int accept(Method method) {
if ( method.getName().equals("method2") ) {
return 1;
} else {
return 0;
}
}
}
private static class MethodInterceptorImpl implements MethodInterceptor {
public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println(method);
return proxy.invokeSuper(obj, args);
}
}
}
jdk动态代理的简单实现:
package proxy.dynamicProxy.jdk;
import java.util.Random;
/**
* 需要代理的具体类继承接口
*/
public class Car implements Moveable {
@Override
public void move() {
//实现开车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
########################################
package proxy.dynamicProxy.jdk;
/**
*jdk实现动态代理模式,必须使用接口
*/
public interface Moveable {
void move();
}
########################################
package proxy.dynamicProxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理者,必须集成InvocationHandler 实现invoke方法
*/
public class TimeHandler implements InvocationHandler {
public TimeHandler(Object target) {
super();
this.target = target;
}
//代理对象
private Object target;
/*
* 只能代理实现了接口的类,没有实现接口的类不能实现JDK动态代理
* 参数:
* proxy 被代理对象
* method 被代理对象的方法
* args 方法的参数
*
* 返回值:
* Object 方法的返回值
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long starttime = System.currentTimeMillis();
System.out.println("汽车开始行驶....");
method.invoke(target);
long endtime = System.currentTimeMillis();
System.out.println("汽车结束行驶.... 汽车行驶时间:"
+ (endtime - starttime) + "毫秒!");
return null;
}
}
#####################################
package proxy.dynamicProxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
/**
* JDK动态代理测试类
*/
public static void main(String[] args) {
Car car = new Car();
InvocationHandler h = new TimeHandler(car);
Class<?> cls = car.getClass();
/**
* loader 类加载器
* interfaces 实现接口
* h InvocationHandler 调用处理者
*/
Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), h);
m.move();
}
}
cglib动态代理简单实现:
package proxy.dynamicProxy.cglib;
public class Train {
public void move(){
System.out.println("火车行驶中...");
}
}
##########################################
package proxy.dynamicProxy.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 CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();//实例化强化剂对象
public Object getProxy(Class clazz){
//设置创建子类的类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 针对类来实现代理,先为目标类生产一个子类,通过方法拦截技术拦截所有父类方法的调用
* 拦截所有目标类(父类)方法的调用
* obj 目标类的实例
* m 目标方法的反射对象
* args 方法的参数
* proxy代理类的实例
*/
@Override
public Object intercept(Object obj, Method m, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("日志开始...");
//代理类调用父类的方法
proxy.invokeSuper(obj, args);
System.out.println("日志结束...");
return null;
}
}
##################################
package proxy.dynamicProxy.cglib;
import proxy.dynamicProxy.cglib.CglibProxy;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Train t = (Train)proxy.getProxy(Train.class);
t.move();
}
}