9、代理模式
AOP底层机制为代理模式,学习AOP之前首先要熟悉代理模式
代理模式:
- 静态代理
- 动态代理
9.1、静态代理
静态代理角色分析:
- 抽象角色:一般使用接口或者抽象类来实现
- 真实角色:被代理的角色
- 代理角色:代理真实角色;代理真是角色后,一般会做一些附属的操作
- 客户:使用代理角色来进行一些操作
代码实现: 我要结婚了
结婚
package com.zhangjiangbo.cn.demo2;
public interface Marry {
public void marry();
}
我
package com.zhangjiangbo.cn.demo2;
public class MyMarry implements Marry{
@Override
public void marry() {
System.out.println("我要结婚了");
}
婚庆公司
package com.zhangjiangbo.cn.demo2;
public class WeddingCompanyProxy implements Marry{
private Marry marry;
public WeddingCompanyProxy(Marry marry) {
this.marry = marry;
}
public WeddingCompanyProxy() {
}
@Override
public void marry() {
marry.marry();
find();
scene();
video();
}
// 找人
public void find(){
System.out.println("召集亲友");
}
// 场景布置
public void scene(){
System.out.println("布置场景");
}
// 录像
public void video(){
System.out.println("录像");
}
}
结婚了
package com.zhangjiangbo.cn.demo2;
public class Clienrt {
public static void main(String[] args) {
MyMarry myMarry = new MyMarry();
WeddingCompanyProxy weddingCompanyProxy = new WeddingCompanyProxy(myMarry);
weddingCompanyProxy.marry();
}
}
打印
可以看到,我就负责结婚,其余召集亲友等都是婚庆公司帮我代理完成的,这种就是静态模式
代理模式的好处
- 可以使真是角色的操作更加纯粹,不用去关注一些公共的业务
- 公共也就交给代理角色,实现了业务分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍
9.2、静态代理加深理解
使用我们常用的CRUD来做实例
创建接口
package com.zhangjiangbo.cn.demo3;
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
创建实现类
package com.zhangjiangbo.cn.demo3;
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}
@Override
public void delete() {
System.out.println("删除了一个用户");
}
@Override
public void update() {
System.out.println("更新了一个用户");
}
@Override
public void select() {
System.out.println("查询了一个用户");
}
}
测试
package com.zhangjiangbo.cn.demo3;
public class Client {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.add();
}
}
打印
现在要求增加日志功能
在不修改原有代码的基础上新增一个代理类也实现UserService接口
package com.zhangjiangbo.cn.demo3;
public class Proxy implements UserService{
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void delete() {
log("delete");
userService.delete();
}
@Override
public void update() {
log("update");
userService.update();
}
@Override
public void select() {
log("select");
userService.select();
}
// 添加日志方法
public void log(String methodName){
System.out.println("使用了"+methodName+"方法");
}
}
修改测试类
package com.zhangjiangbo.cn.demo3;
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
// 创建代理类,将要代理的对象放进来
Proxy proxy = new Proxy();
proxy.setUserService(userService);
proxy.add();
}
}
打印
可以看到我们在不修改原有代码的基础上新增了日志功能。
9.3、动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类,基于接口的动态代理,基于类的动态代理
- 基于接口——JDK动态代理【使用】
- 基于类——cglib
- java字节码实现——javasist
需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序