简述动态代理与hibernate之一

正文

代理设计模式


定义:为其他对象提供一种代理以控制这个对象的访问
通俗一点但是不太确定的讲就是,在执行一个已有对象的方法前切入自己的逻辑,比如要想在某购火车票网站(非12306)购买火车票,就必须注册成为该网站的会员,这就是在购买火车票之前切入购票网站自己的逻辑。
在hibernate中的配置文件中有一个属性是
1
<property name="show_sql">true</property>

该属性的作用是在控制台打印出程序运行中相应的sql语句,在这样的代码中
1
2
3
Session session = new SessionFactory().openSession();
Student mStudent = (Student)session.load(Student.class, new Integer(0));
mStudent.setsName("tom");

如果设置了打印sql语句的属性,那么会在控制台输出相应的sql语句,但是很明显,我们自己定义的对象mStudent中并没有相应的打印sql语句的方法,所以hibernate在后台肯定对我们的mStudent做了手脚
我们先来看看jdk中自带的动态代理Proxy的使用方法。

java动态代理机制


话不多说,直接看源代码
首先定义一个接口

IHello.java

很简单的一个接口,只是定义了一个sayHello方法
1
2
3
4
package com.example.proxy;
public interface IHello {
String sayHello(String name,String name2 );
}

Hello.java

实现了该接口
1
2
3
4
5
6
7
8
9
package com.example.proxy;
public class Hello implements IHello {
@Override
public String sayHello(String name,String name2) {
// TODO Auto-generated method stub
return "hello:"+name+" hello:"+name2;
}
}

定义一个代理类

ProxyHandler.java


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
package com.example.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyHandler implements InvocationHandler{
private Object real;
public ProxyHandler(Object real){
this.real = real;
}
public Object createProxy(){
Class clazz = this.real.getClass();
return Proxy.newProxyInstance(
clazz.getClassLoader(),
clazz.getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("method: "+method.getName()+" is intercepted(被截获)");
System.out.println(args.length);
return method.invoke(this.real, args);
}
}

定义一个操作类

DynamicProxy.java


1
2
3
4
5
6
7
8
package com.example.proxy;
public class DynamicProxy {
public static Object getObject(Object obj){
return new ProxyHandler(obj).createProxy();
}
}

测试类

testProxy.java


1
2
3
4
5
6
7
8
9
10
11
12
import com.example.proxy.DynamicProxy;
import com.example.proxy.Hello;
import com.example.proxy.IHello;
public class testProxy {
public static void main(String[] args) {
// TODO Auto-generated method stub
IHello hello = (IHello)DynamicProxy.getObject(new Hello());
System.out.println(hello.sayHello("tom","mike"));
}
}

运行结果如下:

运行结果表示在运行hello.sayHello()方法时被代理类截获了,此时便可以在方法执行之前切入代理类想要加入的逻辑,比如if判断等之类的,当然这种代理模式,用继承也可以实现,但是如果是继承的话父类的内容便已经固定,子类的内容也是固定的,不够灵活。

文末


博文内容纯原创,如有交流请求,请联系我。