动态代理
定义
给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。
目的
- 通过引入代理对象的方法来间接访问目标对象,防止直接访问对象给系统带来的不必要复杂性。
- 通过代理对象对原有的业务增强。
实现
- 具体实现类与代理类要实现同一个接口
- 代理对象要包含实现对象
例子
//接口
public interface Stu {
public void study();
}
//实现类
public class Student implements Stu{
@Override
public void study(){
System.out.println("studying.....");
}
}
//接口
public interface Teac {
public void teach();
}
//实现类
public class Teacher implements Teac{
@Override
public void teach(){
System.out.println("teaching....");
}
}
//代理类(实现InvocationHandler接口)
public class TestProxy implements InvocationHandler {
private Object person;
public Object getPerson() {
return person;
}
public void setPerson(Object person) {
this.person = person;
}
/**
* 通过Proxy获取动态代理的对象
*/
public Object getProxyInstance(){
return Proxy.newProxyInstance(
person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
this
);
}
/**
* 通过动态代理对方法进行增强
* @param o
* @param method
* @param objects
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//前置增强
doSomeBefore();
//方法调用
Object invoke = method.invoke(person, objects);
//后置增强
doSomeAfter();
return invoke;
}
private void doSomeBefore() {
System.out.println("靠近观察");
}
private void doSomeAfter() {
System.out.println("离开");
}
}
public class ZhangShang {
public static void main(String[] args) throws Exception {
//假设张三是年级主任,且正在巡楼
Teac teacher = new Teacher();
Stu student = new Student();
TestProxy testProxy = new TestProxy();
//观察老师
testProxy.setPerson(teacher);
//这里注意只能强转为接口,而不能强转为实现类
Teac t1 = (Teac)testProxy.getProxyInstance();
//老师的代理实现(进行了增强)
t1.teach();
System.out.println("===========================");
//观察学生
testProxy.setPerson(student);
Stu s1 = (Stu)testProxy.getProxyInstance();
//学生的代理实现(进行了增强)
s1.study();
}
}
(打印效果)
靠近观察
teaching....
离开
===========================
靠近观察
studying.....
离开