简析(纯属个人见解)
动态代理模式 | 产生与实现 | 效率 | 限制 |
---|---|---|---|
JDK | 由java内部的反射机制来实现的 | 反射机制在生成类的过程中比较高效 | 目标类基于统一的接口 |
Cglib | 借助asm来实现的 | asm在生成类之后的相关执行过程中比较高效 | 无(可直接代理对象) |
AOP
AOP小结:从上述简析,jdk与cglib各有千秋。Spring AOP的源码中用到了这两种动态代理来实现拦截切入功能。
所以,jdk动态代理和cglib动态代理两种方法同时存在。
JDK动态代理模拟AOP模式
首先,总所周知 advice(AOP通知/增强) 有前置,后置,异常,最终,以及环绕通知。此列以前置通知模拟。
public interface BeforeAdvice(){
/**
**前置通知接口方法
**/
public void before();
}
/**
**1.将JDK代理工厂化
**
**/
public FactoryDemo(){
private Object target;//需要代理的目标对象
private BeforeAdvice beforeAdvice;//前置通知接口对象
(..添加get && set 方法..)
//返回代理对象
public Object create(){
ClassLoader classLoader = target.getClass().getClassLoader();//获取目标对象加载器
//目标对象接口类数组
Class[] interfaces = target.getClass().getInterfaces();
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object arg0, Method method, Object[] arg2)
throws Throwable {
// TODO Auto-generated method stub
if(beforeAdvice != null){
beforeAdvice.before();
}
//目标对象的方法反射
Object result = method.invoke(target, arg2);
return result;
}
};
//返回代理对象
Object proxyObject = Proxy.newProxyInstance(loader, interfaces, invocationHandler);
return proxyObject;
}
}
/**
**1.首先JDK动态代理,前提 接口!!!
**假设 有个接口类 UserService(方法add();)
**接口实现类 UserServiceImpl({System.out.println("****")})
**/
@Test
public void Test(){
FactoryDemo demo = new FactoryDemo();//实例化工厂对象
demo.setBeforeAdvice(new BeforeAdvice() {
@Override
public void before() {
// TODO Auto-generated method stub
System.err.println("前置增强点.....");
}
});
UserService userService= new UserServiceImpl();
demo.setTarget(userService);
//调用工厂化代理方法
UserService userService1= (userService) demo.create();
userService1.add();
}
以上代码略有省略,欢迎指错,批评小白,以及讨论。cglib 测试下一版发布。。。。。。