什么是动态代理模式
动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理,作用是可以对目标对象进行增强,实现动态增加功能扩展的作用。
实现:
1,使用jdk的动态代理方式,目标类需要实现一个接口,代理类需要实现InvocationHandler接口。
2,使用cglib的动态代理方式,目标类不能被final修饰,在代理过程中会自动生成一个目标类的子类,代理类需要实现MethodInterceptor接口,cglib底层是用字节码技术实现的。
使用jdk的动态代理方式
目标类
public class Man implements Person {
public void eat() {
System.out.println("have a meal ...");
}
}
目标类的抽象
public interface Person {
void eat();
}
代理类
//代理类
public class PersonProxy implements InvocationHandler {
//目标接口
private Person person;
public PersonProxy(Person person) {
this.person = person;
}
//对目标进行增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("刷牙....");
method.invoke(person, args);
System.out.println("漱口...");
return null;
}
//返回代理增强之后的对象
public Person newPerson() {
return (Person) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this);
}
}
测试
public class Test {
public static void main(String[] args) {
Man man = new Man();
PersonProxy personProxy = new PersonProxy(man);
//代理增强之后的对象
Person person = personProxy.newPerson();
person.eat();
}
}
使用cglib的动态代理方式
目标类
public class Man implements Person {
public void eat() {
System.out.println("have a meal ...");
}
}
代理类
//代理类
public class PersonProxy implements MethodInterceptor {
//目标接口
private Person person;
public PersonProxy(Person person) {
this.person = person;
}
//相当于JDK动态代理中的绑定
public Object getInstance() {
Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
//为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
enhancer.setSuperclass(person.getClass());
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("刷牙....");
method.invoke(person, objects);
System.out.println("漱口...");
return null;
}
}
测试
public class Test {
public static void main(String[] args) {
Man man = new Man();
PersonProxy personProxy = new PersonProxy(man);
//代理增强之后的对象
Person person = (Person) personProxy.getInstance();
person.eat();
}
}