代理的设计模式解决了什么问题?
代理的设计模式 解决的问题:能够动态的监控一个类 中所有方法的执行 以及在这个方法的执行的前后动态植入咋们的代码
代理:简单的说就是对原来的功能的增强
比如:为业务逻辑层提供事务
@Configuration
Spring整合iBatis
1.静态代理模式
必须实现接口
1.1被代理类的接口
public interface IUserService {
void zz();
}
1.2 被代理类
public class UserService implements IUserService{
/**
* 转账这个方法
*/
public void zz(){
System.out.println("锁定张三的账户");
System.out.println("张三的账户预减1000元");
System.out.println("检测李四的账户是否可用");
System.out.println("李四的账户增加1000元");
}
}
1.3 代理类
public class UserServiceProxy implements IUserService{
private IUserService userService;
public UserServiceProxy(IUserService userService ){
this.userService=userService;
}
@Override
public void zz() {
System.out.println("添加事务");
userService.zz();
System.out.println("提交事务");
}
}
2.动态代理
动态:被代理的类的对象是自动生成的
代理的类是自动生成的
被代理的类的对象也是自动生成的
JDK代理:原因是使用的是JDK本身的API
前提:被代理的类 必须要实现接口
2.1被代理类的接口
public interface IUserService {
void zz();
}
2.2 被代理的类
public class UserService implements IUserService {
/**
* 转账这个方法
*/
public void zz(){
System.out.println("锁定张三的账户");
System.out.println("张三的账户预减1000元");
System.out.println("检测李四的账户是否可用");
System.out.println("李四的账户增加1000元");
}
}
2.3 代理类实现
public static void main(String[] args){
/**
* 第一个参数:classloader:表示的是类加载器 写法是死的 类.class.getClassLoader
* 第二个参数:interfaces:当前类实现的接口 之所以要这个东西 是因为 生成代理类的时候 需要实现接口
* 1:被代理的是个类:类.class.getInterface
* 2:被代理的是是个接口: new Class[]{接口.class}
* 第三个参数:invationHandle
* 方法的监听的回调接口----当你执行这个接口中的某一个方法的时候就会自动的回调到这个方法中来
*/
IUserService userService= (IUserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
UserService.class.getInterfaces(),
new InvocationHandler() { //执行到每一个方法都会执行到这里来
/**
*
* @param proxy :代理对象
* @param method :当前执行的方法
* @param args :当前执行方法的参数封装
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在方法执行的前后进行拓展
System.out.println("打开事务");
Object invoke = method.invoke(new UserService(), args);
System.out.println("关闭事务");
return invoke;
}
}
);
3.cglib代理
静态代理和动态代理都有一个前提:被代理的类必须实现接口
假设一个类 没有实现接口需要增强 怎么办呢?
CGLIB代理在这种场景下 就应运而生了…
CGLIB代理本身是可以代理任意的一个类 这个类可以不实现接口 也可以实现接口
3.1 被代理的类
public class UserService{
/**
* 转账这个方法
*/
public void zz(){
System.out.println("锁定张三的账户");
System.out.println("张三的账户预减1000元");
System.out.println("检测李四的账户是否可用");
System.out.println("李四的账户增加1000元");
}
}
3.2 代理的类
public class UserServiceProxy{
/**
* 获取这个代理类
* @return
*/
public static UserService getUserServiceProxy(){
Enhancer enhancer=new Enhancer();
//设置生成的类的爹是谁
enhancer.setSuperclass(UserService.class);
//设置方法监听的回调
enhancer.setCallback(new MyMethodInterceptor());
return (UserService) enhancer.create();
}
/**
* 方法的监听
*/
static class MyMethodInterceptor implements MethodInterceptor{
/**
*
* @param obj:代理对象
* @param method :当前执行的方法
* @param args :当前执行方法的参数
* @param proxy :这个是方法代理
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//在这里进行增强
System.out.println("开启事务");
Object invoke = method.invoke(new UserService(), args);
System.out.println("提交事务");
return invoke;
}
}
}
3.3 测试实现
public class Test001 {
public static void main(String[] args){
UserService userServiceProxy = UserServiceProxy.getUserServiceProxy();
userServiceProxy.zz();
}
}