cglib使用实例
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
import org.springframework.transaction.annotation.Transactional;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
* 代理工厂
* Created by Blysin on 2017/7/25.
*/
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public <T> T getInstance() {
Class<?> clazz = target.getClass();
Object proxy = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Annotation trans = method.getAnnotation(Transactional.class);
Object result = null;
if (trans != null) {//如果有Transactional这个注解,则实现事务
System.out.println("----开启事务----");
result = method.invoke(target, args);//让目标对象来执行,而不是proxy对象来执行
System.out.println("----提交事务----");
} else {
result = method.invoke(target, args);
}
return result;
}
});
return (T) proxy;
}
}
实现说明:
构造器传入一个被代理的对象,cglib.Proxy的静态方法newProxyInstance(),传入被代理类的类加载器,被代理类的所有接口,以及一个代理实现类。代理实现类需要实现invoke方法,该方法形参为代理对象,方法,方法形参,调用代理类的方法全部都会经过这个代理实现类。
在例子中,首先获取方法的Transactional.class事务接口,如果存在的话进行事务操作,如果不存在的会则直接让被代理类调用该方法。可以看出,动态代理就是基于反射来实现的。
cglib有jdkProxy的区别
jdkProxy的代理使用与cglib基本一致,在实例中可以看出代理的使用是基于接口实现的,因此如果被代理被没有实现接口就无法使用jdkProxy。jdk的实现原理是动态创建一个代理类,实现了被代理类的接口
class $jdkProxy implements UserService{}
而cglib可以解决对无实现接口的类的代理,cglib的原理是动态创建一个代理被,继承与目标类,因此目标类不能为final类。
AOP的实现原理
Spring AOP总和利用了jdkProxy和cglib代理,判断是否用实现接口,从而决定用哪种代理方式。