1、介绍
定义:
代理模式:给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用
拿买车做打比方。
没有使用代理的情况,一个人去买二手车,他首先到店里验车,然后付款,最后自己再去车管所上牌。
使用代理的情况,他只需要找个中介,然后把款付给中介,让中介帮我们去店里验车,付款,然后再帮我们去车管所上牌。
分类:
按照代理创建的时期来进行分类, 可以分成2类:
- 静态代理:编译期间 代理类的 .class 文件已经被创建好了
- 动代理态:运行期间 通过反射机制动态创建代理对象 动态代理有2种( JDK的动态代理 、cglib的动态代理)
总结:
代理模式是:通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
简单的说,就是可以在业务方法执行之前,进行一些逻辑方法的处理,在业务方法执行之后,再进行另一些逻辑方法的处理。可以用代理模式来做 日志记录、权限控制、事务处理、性能统计等
2、静态代理
案例:
有个 UserService 接口,在接口中定义了一个 save 方法。有个 UserServiceImpl 类实现了 UserService 接口,重写了 save方法。此时我们需要在 不改变 UserServiceImpl 类的情况下,为 save 方法执行之前 添加开启事务操作, 在执行 save 方法后 执行提交事务操作
例如:
原来的 save 方法:
public void save(User user) {
System.out.println("开始事务。。。。");
System.out.println("正在保存 ->" + user);
System.out.println("提交事务。。。。");
}
改造后的 save 方法:
public void save(User user) {
System.out.println("正在保存 ->" + user);
}
思考:为什么要把事务处理的方法抽取处理?
试想下,我们很多方法都需要进行事务的处理,而事务处理方法的逻辑又是固定的,如果这些方法都自己进行事务处理,那么在我们的业务方法中会冗余很多这样的代码,不便于后期的维护和升级
案例操作:
实体类:User
package com.lcy.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
}
业务层接口:UserService
package com.lcy.service;
import com.lcy.model.User;
public interface UserService {
void save(User user);
}
接口的实现类:UserServiceImpl
package com.lcy.service.impl;
import com.lcy.model.User;
import com.lcy.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
System.out.println("正在保存 ->" + user);
}
}
代理类:UserServiceImplProxy
package com.lcy.proxy;
import com.lcy.model.User;
import com.lcy.service.UserService;
public class UserServiceImplProxy implements UserService {
private UserService userService;
public UserServiceImplProxy(UserService userService) {
this.userService = userService;
}
@Override
public void save(User user) {
System.out.println("开始事务。。。。");
userService.save(user);
System.out.println("提交事务。。。。");
}
}
测试类:UserServiceImplProxyTest
package com.lcy.test;
import com.lcy.model.User;
import com.lcy.proxy.UserServiceImplProxy;
import com.lcy.service.UserService;
import com.lcy.service.impl.UserServiceImpl;
public class UserServiceImplProxyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService userServiceProxy = new UserServiceImplProxy(userService);
userServiceProxy.save(new User(2, "张三"));
}
}
运行结果:
设计分析图:
3、静态代理的优缺点
优点:在不改动原有的类的情况下,对其功能进行扩展
缺点:由于代理类也要实现接口,一旦接口发生变化(新增或删除方法),代理类也要进行相应的修改。