1.代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。简单地说就是为其他对象提供一种代理以控制对这个对象的访问。
2.代理模式的作用:在某些情况下,一个对象不能或者不适合直接引用另一个对象,这种情况下就可以用代理类作为中间媒介间接地引用目标对象,代理模式作为中介在其中起到了隔离作用。同时还可以作为被代理类的拓展,对其功能进行拓展加入根据需要增加功能。而代理模式的主要特征就是代理类和被代理类拥有相同的接口,这也是代理模式的一个缺点。
3.代理模式分类: 静态代理在java虚拟机进行编译时就将接口、被代理类、代理类等编译完成,因此当代理类较多时占用资源效率较低;动态代理可以利用java的反射机制在运行时根据需要才创建代理对象。
1.静态代理:①定义一个接口;②定义一个接口的具体实现类,实现类中的方法要将接口中的具体功能实现;③定义一个代理类实现同样的接口,代理类中的方法可以增加一些功能,但主要是调用具体实现类中相应的方法用;
①定义一个接口
/*
* 接口:代理对象与被代理对象要实现的共同接口
*/
public interface Persion {
public void getPersion();
}
②定义一个接口的具体实现类,实现类中的方法要将接口中的具体功能实现;
/*
* 被代理对象:要实现Persion接口
*
*/
public class Teacher implements Persion{
@Override
public void getPersion() {
System.out.println("我是被代理对象,I'm a teacher!");
}
}
③定义一个代理类实现同样的接口,代理类中的方法可以增加一些功能,但主要是调用具体实现类中相应的方法用;
/*
* 代理对象:要实现Persion
*/
public class ProxyTeacher implements Persion {
// 创建被代理对象
private Teacher teacher;
public ProxyTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public void getPersion() {
System.out.println("我是代理对象。。。。");
// 执行被代理对象那个的方法
teacher.getPersion();
}
}
④测试类
/*
* 这是测试类
*/
public class TestProxy {
public static void main(String[] args){
//被代理对象
Teacher teacher = new Teacher();
//简历代理关系
ProxyTeacher proxy=new ProxyTeacher(teacher);
//调用被代理对象的方法
proxy.getPersion();
}
}
运行结果:
2.动态态代理:①定义一个接口;②定义一个接口的具体实现类,实现类中的方法要将接口中的具体功能实现;③定义一个代理类无需实现接口,但必须指明接口类型。在代理类的方法中返回所需被代理类的对象;
①定义一个接口;
/*
* 接口:代理对象与被代理对象要实现的共同接口
*/
public interface Persion {
public void getPersion();
}
②定义一个接口的具体实现类,实现类中的方法要将接口中的具体功能实现;
/*
* 被代理对象
*
*/
public class Teacher implements Persion{
public String name;
public Teacher(String name){
this.name=name;
}
@Override
public void getPersion() {
System.out.println("我是被代理对象,我是一个:"+name);
}
}
③定义一个代理类无需实现接口,但必须指明接口类型。在代理类的方法中返回所需被代理类的对象;
/*
* 动态代理:不需要实现接口,但必须指定接口类型
*/
public class DynamicProxy {
// 创建被代理对象
private Object target;
// 通过构造器确定被代理对象
public DynamicProxy(Object target) {
this.target = target;
}
// 获取代理对象
public Object getProxyInstace() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("这是动态代理!");
// 调用被代理对象的目标方法
Object invoke = method.invoke(target, args);
return invoke;
}
});
}
}
④测试类:
/*
* 动态代理的测试方法
*/
public class TestDynamicProxy {
public static void main(String[] args){
//创建被代理对象
Persion persion=new Teacher("老师");
//创建代理对象
Persion proxy= (Persion) (new DynamicProxy(persion).getProxyInstace());
//调用被代理对象的目标方法
proxy.getPersion();
}
}
⑤运行结果: