spring
AOP的实现——代理模式


1.要求有接口I
2.Spring给被代理类S生成代理类P,该代理类P实现了S的接口I,并且P持有了S的实例
3.代理类在实现共同方法时,先执行代理逻辑,再调用被代理类的相应方法,实现了不改变被代理类,但是提供了新的功能
4.当我们从spring按接口获取bean时,实际得到的是代理类的实例,当调用方法时,执行的是代理类的方法
**动态代理:
1.JDK动态代理
2.cglb动态代理**
代理模式结构
• 代理类和被代理类必须实现同一个接口
• 代理类持有被代理类的实例
• 调用代理类的方法时,执行代理逻辑,并调用被代理类的方法
代理模式,能够实现在不改变被代理类的代码的情况下,为该类添加功能
待解决的问题:给定任意一个类,支持动态生成代理类
JDK动态代理
用接口实现,要求必须有接口
java.lang.reflect.Proxy
java.lang.reflect.Proxy#newProxyInstance
public static Object newProxyInstance(ClassLoader loader, //类加载器
Class<?>[] interfaces,//代理类需要实现的接口
InvocationHandler h // 拦截方法并添加代理逻辑功能
)
InvocationHandler
public Object invoke(Object proxy,
Method method, //被拦截的方法
Object[] args //被拦截的方法的参数
)
throws Throwable;
// public Object invoke(Object obj 目标对象, Object... args 参数)
//前置通知
try{
Object result = method.invoke(目标对象,args)
}catch(exception){
//异常通知
}finally{
//最终通知
}
//后置通知
package com.woniuxy.framework.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class JdkProxyFactory {
/**
* 生成代理类
* @param target 目标对象
* @return
*/
public static Object getProxy(final Object target){
//类加载器
ClassLoader classloader = target.getClass().getClassLoader();
//目标对象的接口
Class<?>[] interfaces = target.getClass().getInterfaces();
//拦截逻辑
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用"+method+",参数为"+ Arrays.toString(args));
long before = System.currentTimeMillis();
//调用被代理类的方法
Object result = method.invoke(target,args);
long after = System.currentTimeMillis();
System.out.println("调用"+method+"执行时长为"+(after-before));
return result;
}
};
Object proxy = Proxy.newProxyInstance(classloader, interfaces, invocationHandler);
return proxy;
}
}
public class JdkProxyApp {
public static void main(String[] args) {
OrderService orderService = new OrderServiceImpl();
OrderService orderServiceProxy = (OrderService) JdkProxyFactory.getProxy(orderService);
double result = orderServiceProxy.createOrder(1, 10);
System.out.println("计算结果为:"+result);
UserService userServiceProxy = (UserService) JdkProxyFactory.getProxy(new UserServiceImpl());
userServiceProxy.login("zhangsan","wohenshuai");
}
}
Cglib动态代理
Enhancer 增强器
MethodInterceptor 方法拦截器
package com.woniuxy.framework.proxy.cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;
public class CglibProxyFactory {
/**
*
* @param target 目标对象
* @return 代理类
*/
public static Object getProxy(final Object target){
//
Enhancer enhancer = new Enhancer();
//设置父类,使用继承方式实现动态代理
enhancer.setSuperclass(target.getClass());
//设置拦截逻辑
MethodInterceptor callback = new MethodInterceptor() {
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//前置通知
System.out.println("调用方法"+method.getName()+" 参数为"+ Arrays.toString(args));
Object result = method.invoke(target, args);
//后置通知
return result;
}
};
enhancer.setCallback(callback);
//创建代理对象
return enhancer.create();
}
}
package com.woniuxy.framework.proxy.cglib;
import com.woniuxy.framework.service.ChapterServiceImpl;
public class CglibProxyApp {
public static void main(String[] args) {
ChapterServiceImpl proxy = (ChapterServiceImpl) CglibProxyFactory.getProxy(new ChapterServiceImpl());
int result = proxy.count("李四");
System.out.println("结果为"+result);
}
}
面试可能要问的
AOP 跟IoC是什么关系?
IoC是AOP的基础
IoC容器,控制权反转,从调用方到了spring容器
容器负责实例化,依赖注入
【i】OrderService
【c】impl.OrderServiceImpl @Service
Spring会实例化OrderServiceImpl
新增切面,拦截所有的service类的所有方法,AOP
需要动态生成OrderServiceImpl的代理类 (JDK动态代理、Cglib动态代理)
OrderServiceProxy 实现了OrderService接口,加入了代理逻辑(通知)
将代理类放入spring容器中
获取时,使用接口来获取Bean,得到的实际上代理类的实例
调用时,先执行代理逻辑,代理类的实例自动调用目标对象的相应方法

AOP回顾
概念
名词解释
通知类型(5种)
典型的使用场景——声明式事务
AOP的实现——代理模式
• 接口实现
• 继承实现
动态代理
• jdk动态代理
• cglib动态代理
本文介绍了Spring AOP的实现原理,重点讲解了两种动态代理方式:JDK动态代理和CGLIB动态代理。通过示例代码展示了如何生成代理类及执行代理逻辑。
687

被折叠的 条评论
为什么被折叠?



