代理机制
Spring 的AOP 部分使用使用JDK动态代理,部分使用CGLIB来为目标对象创建代理。如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理;如果目标对象没有实现任何接口,则会创建CGLIB动态代理。CGLIB是第三方包,从Spring4.3开始就无需再次导入包了。
注意
1)客户端直接调用与目标类相对应的代理类的功能,
2)为了保证代理类与目标类具有相同功能,代理类与目标类必须实现相同的接口
代理是实现AOP的核心和关键技术。只要是AOP,就一定会涉及代理技术
. 代理技术的分类
按照是否是在程序运行期间产生代理类可以将代理分为静态代理和动态代理
1.静态代理:就是手动为每一个目标类的每一个方法都增加交叉业务,也就是手动为每一个目标类增加代理类
缺点:如果目标类数量非常多或者目标类中的功能非常多,直接使用静态代理的方式来为目标类增加交叉业务会非常的繁琐。
2.动态代理:通过特定的设置,在程序运行期间指示JVM动态地生成类的字节码。这种动态生成的类往往被用作代理类,即动态代理类。也就是运行时做 编译的事情并且把生成的字节码加载成这个类的Class对象
首先是静态代理
创建一个抽象角色,比如咋们平时做的用户业务,抽象起来就是增删改查!
编写接口方法
package com.ice.spring.service;
//抽象角色:增删改查业务
public interface UserService {
void add();
void delete();
void update();
void query();
}
我们需要一个真实对象来完成这些增删改查操作,也就是接口的实现类
package com.ice.spring.service;
//真实对象,完成增删改查操作的人
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void query() {
System.out.println("查询了一个用户");
}
}
现在我们需要增加一个日志功能,怎么实现!
思路1 :在实现类上增加代码 繁琐,影响业务
思路2:使用静态代理来做,能够不改变原来的业务情况下,可以实现此功能
设置一个代理类来处理日志! 代理角色
package com.ice.spring.service;
//代理角色,在这里面增加日志的实现
public class UserServiceProxy implements UserService {
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
public void add() {
log("add");
userService.add();
}
public void delete() {
log("delete");
userService.delete();
}
public void update() {
log("update");
userService.update();
}
public void query() {
log("query");
userService.query();
}
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
测试访问类:
package com.ice.spring;
import com.ice