设计模式-代理模式

  1. 代理模式
    1. 静态代理
    2. 动态代理
    3. Cglib代理

代理模式

静态代理

  • 目标类和代理类实现同一接口
  • 对功能进行增强
  • 缺点: 因为目标类和代理类实现了同一接口,此时接口一旦发生改变,两个类都必须同时实现新增的功能(动态代理可以解决这一缺点)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* @USER: lynn
* @DATE: 2020/4/26
**/
public class 静态代理 {
public static void main(String[] args) {
数学老师 mathTeacher1 = new 数学老师();
数学教授 mathTeacher2 = new 数学教授(mathTeacher1);
mathTeacher2.教书();
}
}
interface 老师{
void 教书();
}
class 数学老师 implements 老师{
@Override
public void 教书() {
System.out.println("教数学");
}
}

class 数学教授 implements 老师{

private 数学老师 math;

public 数学教授(数学老师 math) {
this.math = math;
}

@Override
public void 教书() {
System.out.println("教物理");
math.教书();
}
}

动态代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

/**
* @USER: lynn
* @DATE: 2020/4/26
**/
public class 动态代理 {
public static void main(String[] args) {
DynamicProxy dynamicProxy = new DynamicProxy(new 董事长(),new 助理());
职工 worker = (职工)dynamicProxy.newInstance();
worker.work();
}
}
interface 职工{
void work();
}
class 董事长 implements 职工{
@Override
public void work() {
System.out.println("做董事长该干的事");
}
}
class 助理 {
public void beforeWork(){
System.out.println("work前");
}
public void afterWork(){
System.out.println("work后");
}
}

class DynamicProxy{
private Object object;
private 助理 helper;

public DynamicProxy(Object object, 助理 helper) {
this.object = object;
this.helper = helper;
}

public Object newInstance(){
Class<?> clas = this.object.getClass();
return Proxy.newProxyInstance(clas.getClassLoader(), clas.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
helper.beforeWork();
Object obj = method.invoke(object,args);
helper.afterWork();
return obj;
}
});
}
}

Cglib代理

  • Spring中AOP的实现原理就是用的代理模式–>动态代理+Cglib代理
    • 如果目标类实现了接口,Spring底层AOP就调用动态代理,否则调用Cglib代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

/**
* @USER: lynn
* @DATE: 2020/4/26
**/
public class Cglib代理 {
public static void main(String[] args) {
CrudDaoInterceptor interceptor = new CrudDaoInterceptor(new CrudDaoImpl(),new Transaction());
CrudDaoImpl proxy = (CrudDaoImpl) interceptor.getObject();
proxy.delete();
}

}
class CrudDaoImpl{
public void select(){
System.out.println("select * from table");
}
public void insert(){
System.out.println("insert into table values()");
}
public void delete(){
System.out.println("delete from table where id = ?");
}
public void update(){
System.out.println("update table set id = ? where name = ?");
}
}

class Transaction{
public void openTransaction(){
System.out.println("开启事务");
}
public void commitTransaction(){
System.out.println("提交事务");
}
}

class CrudDaoInterceptor implements MethodInterceptor{

private Object object;
private Transaction transaction; //切面

public CrudDaoInterceptor(Object object, Transaction transaction) {
this.object = object;
this.transaction = transaction;
}

public Object getObject() {
Enhancer enhancer = new Enhancer();
Class<?> clazz = this.object.getClass();
enhancer.setCallback(this);
enhancer.setClassLoader(clazz.getClassLoader());
enhancer.setInterfaces(clazz.getInterfaces());
enhancer.setSuperclass(clazz);
return enhancer.create();
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
String methodName = method.getName();
System.out.println("执行的方法名为:"+methodName);
if ("delete".equals(methodName)){
transaction.openTransaction();
method.invoke(object,objects);
transaction.commitTransaction();
}

return null;
}
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yanglau0527@gmail.com

文章标题:设计模式-代理模式

文章字数:668

本文作者:Cynaith

发布时间:2020-05-02, 01:22:51

最后更新:2020-05-02, 01:24:19

原始链接:https://cynaith.github.io/2020/05/02/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏