老生常谈的问题,spring的aop是什么,用到的设计模式是什么,进而又会谈到静态代理和动态代理上。之前看过一些这方面的文章,也照着敲了一些代码,可是coding这个事啊,总是写了忘,忘了写。今天就简单记录一下
- 代理是什么
- 代理能降低代码耦合度,将枝节性代码和功能性代码分开
- 没有代理会怎样
- 代码之间耦合度较高,移植困难,可重用性降低
- 枝节性代码应该监视着功能性代码,然后采取行动,而不是功能性代码通知枝节性代码采取行动。这好比吟游诗人应该是主动记录骑士的功绩而不是骑士主 动要求诗人记录自己的功绩
- 应用
- AOP 实现
- 权限控制
- 日志控制
- 事务管理
静态代理和动态代理区别
- 静态代理
- 一个抽象对象(从代码实现上讲,并不是必须的)
- 代理类 — 拥有真实类的对象
- 委托类
- 每个委托类需要一个代理类
- 动态代理
- 解决静态代理问题
- 代码膨胀
- 代理类需要事先知道被代理对象
- 实现统一的代理对象
- 静态代理
好了,上面这些唠完了,来看一下代码,这里只是一些简单的实现,更加复杂的可以参考别人的代码
静态代理
1. 接口类。其实这里可以不写这个公共接口。它的作用只是体现了面向接口编程
/**
* 打卡
* /
public interface Clock {
void startWork();
void endWork();
}
2.委托类。即真正的业务类
/**
* 上班
*/
public class Work implements Clock {
@Override
public void startWork() {
System.out.println("写代码喽!");
}
@Override
public void endWork() {
System.out.println("回家加班喽!");
}
}
3.代理类。持有委托类对象。
/**
* 代理
*/
public class WorkProxy implements Clock {
private Work work;
public WorkProxy(Work work) {
this.work = work;
}
@Override
public void startWork() {
System.out.println("上班打卡");
work.startWork();
}
@Override
public void endWork() {
System.out.println("下班打卡");
work.endWork();
}
}
4.测试类
/**
* 测试
*/
public class Test {
public static void main(String[] args) {
//如果不使用接口
Work work = new Work();
WorkProxy workProxy = new WorkProxy(work);
workProxy.startWork();
workProxy.endWork();
//使用接口的话,这里可以方便的使用多态
//Clock clock = new Work();
Clock clock = new WorkProxy(new Work());
clock.startWork();
}
}
动态代理
- 公共接口和实现类copy上面的
- 这里再新增一个实现类。体现动态代理一次代理多处使用的优点
/**
* 学习
*/
public class Study implements Clock {
@Override
public void startWork() {
System.out.println("我要学习了");
}
@Override
public void endWork() {
System.out.println("放学回家了");
}
}
3.代理类 持有委托类对象 实现反射里面的InvocationHandler接口即可
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object target) {
this.object = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("早上9点 上班打卡!");
Object result = method.invoke(object, args);
System.out.println("晚上9点 下班打卡!");
return result;
}
}
4.测试类
/**
* 测试
*/
public class Test {
public static void main(String[] args) {
//DynamicProxy proxy = new DynamicProxy(new Study());
DynamicProxy proxy = new DynamicProxy(new Work());
Clock clock = (Clock) Proxy.newProxyInstance(Clock.class.getClassLoader()
, Work.class.getInterfaces(), proxy);
clock.startWork();
}
}