一 概述
1 分类
静态代理:在程序运行前就已经存在代理类的字节码文件,代理对象和真实对象的关系在运行前就确定了。(代理类及对象要自行创建)
动态代理:代理类是在程序运行期间由 JVM 通过反射等机制动态的生成的,不存在代理类的字节码文件,动态生成字节码对象,代理对象和真实对象的关系是在程序运行时期才确定的。(代理类及对象不需要自行创建)
2 动态代理实现方式
真实类有接口使用 JDK 动态代理;
真实类没实现接口使用 CGLIB 或 Javassist 组件。
二 静态代理
1 介绍
静态代理是一种代理模式,其中代理对象在编译时就确定下来,而不是在运行时动态创建。静态代理由业务实现类、业务代理类两部分组成。业务实现类负责实现主要的业务方法,业务代理类负责对调用的业务方法作拦截、过滤、预处理。
静态代理的优点是可以实现对目标方法的扩展,控制真实对象的访问权限,避免创建大对象,以及增强真实对象功能。业务类只需要关注业务逻辑本身,保证了业务类的重用性。把真实对象隐藏起来了,保护真实对象。
缺点是如果一个代理类只能对一个业务接口的实现类进行包装,如果有多个业务接口的话就要定义很多实现类和代理类才行。而且,如果代理类对业务方法的预处理、调用后操作都是一样的(比如:调用前输出提示、调用后自动关闭连接),则多个代理类就会有很多重复代码。
2 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
3 业务类
// 真实类与代理类需实现相同的接口
public interface EmployeeService {
/*员工保存*/
public int save(String username,String password);
}
// 真实类
public class EmployeeServiceImpl implements EmployeeService {
@Override
public int save(String username, String password) {
System.out.println("员工姓名:"+username+"密码:"+password);
return 0;
}
}
4 代理类
public class EmployeeServiceProxy implements EmployeeService {
/*setter注入真实对象,增加事务操作*/
private EmployeeServiceImpl employeeService;
public void setEmployeeService(EmployeeServiceImpl employeeService) {
this.employeeService = employeeService;
}
/*setter注入事务管理对象*/
private TransactionManager transactionManager;
public void setTransactionManager(TransactionManager transactionManager) {
this