代理机制
采用代理模式 主要为了解耦 将公共的通用方法放到代理对象中
业务层 专注于业务代码
代理的特点:
1. 为什么使用代理 ? 因为不方便
2. 代理的作用 代理要解决(扩展)某些实际的问题
3. 用户最终执行目标方法
就是为了解耦 灵活的代理代码
JDK模式
- JDK代理模式是Java原生提供的API
- JDK代理要求: 被代理者必须 要么是 接口 , 要么是 实现类
- 灵活: 代理对象应该开起来和被代理者一模一样(里面的方法相同)
使用JDK
创建动态代理
public class JDKProxy {
//提供获取动态代理的方法
//返回动态代理的方法
public static Object getProxy(Object target){// 传入 目标对象
//获取类加载器
ClassLoader classLoader = target.getClass().getClassLoader();
//获取接口数组类型
Class<?>[] interfaces = target.getClass().getInterfaces();
//代理对象指定方法时的回调方法 代理对象调用方法时执行 InvocationHandler
return Proxy.newProxyInstance(classLoader,interfaces,invoke(target));
}
//构建InvocationHandler的方法 传入目标对象
public static InvocationHandler invoke(Object target){//返回一个 InvocationHandler
return new InvocationHandler() {// 是接口 需要实现里面的方法
@Override
//Object proxy 代理对象, Method method 目标方法, Object[] args 参数数组
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//开启事务
System.out.println("事务的开启");
//执行目标方法
// 传入 目标对象 和 参数列表
// 获取目标方法的返回值
Object result = method.invoke(target, args);//调用目标方法
//提交 事务
System.out.println("事务的提交");
//返回 方法
return result;
}
};
}
}
另一种写法
public static Object getProxy(Object target){
ClassLoader classLoader = target.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
return Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
//调用方法
Object invoke = method.invoke(target, args);
//提交事务
System.out.println("事务提交");
//返回 方法
return invoke;
}
});
}
CGLib 代理模式
jdk
代理 必须 有实现 接口 没有接口不能运行
cgblib
代理 要求被代理者有没有接口都可以
代理对象必须是目标对象的 子类
public class CGLibProxy {
public static Object getProxy(Object target){
//创建增强器
Enhancer enhancer = new Enhancer();
//代理对象时 目标对象的 子集
//设定 父级:目标对象
enhancer.setSuperclass(target.getClass());
//定义回调方法 代理对象执行目标方法调用
enhancer.setCallback(getMethodInterceptor(target));
//创建代理对象 并返回
return enhancer.create();
}
public static MethodInterceptor getMethodInterceptor(Object target){
return new MethodInterceptor() {
@Override // Object o 代理对象, Method method 目标方法, Object[] objects 参数数组 , methodProxy 代理的方法
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始事务CGlib");
//执行 目标 方法
Object result = method.invoke(target, objects);
System.out.println("事务提交CGlib");
//返回 方法
return result;
}
};
}
}
另一种写法
public static Object getProxy2(Object target){
//创建增强器
Enhancer enhancer = new Enhancer();
//设定 父级
enhancer.setSuperclass(target.getClass());
//定义回调
enhancer.setCallback(new MethodInterceptor() {
@Override// Object o 代理对象, Method method 目标方法, Object[] objects 参数数组 , methodProxy 代理的方法
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始事务CGlib");
//执行方法
Object result = method.invoke(target, objects);
System.out.println("事务提交CGlib");
//返回 方法
return result;
}
});
return enhancer.create();
}
两种模式的使用
JDK
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//Spring对象管理容器
UserService service = context.getBean(UserService.class);//获取接口类
UserService proxy = (UserService)JDKProxy.getProxy(service);//代理执行
proxy.addUser();//执行方法
CGLib
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//Spring对象管理容器
UserService service = context.getBean(UserServiceImpl.class);//获取接口类
UserService proxy = (UserService) CGLibProxy.getProxy(service);//代理执行
proxy.addUser();//执行方法