import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
interface 动物{
public void eat();
public void say();
}
class 狗 implements 动物{
public void eat(){
System.out.println("狗在吃..");
}
public void say(){
System.out.println("狗在叫..");
}
}
public class Demo01 {
public static void main(String[] args) {
//需求: 对狗类的say方法进行改造
//方式1:继承
class 继承狗 extends 狗{
@Override
public void say() {
System.out.println("狗在汪汪汪汪的叫..");
}
}
狗 dog = new 继承狗();
dog.eat();
dog.say();
//方式2:装饰设计模式---用同类对象构造本类对象,从而对本类对象进行修复或增强。
class 装饰狗{
private 狗 dog;
public 装饰狗(狗 dog) {
this.dog = dog;
}
public void eat(){
dog.eat();
}
public void say(){
System.out.println("狗在汪汪汪汪的叫..");
}
}
狗 dogx = new 狗();
装饰狗 dog = new 装饰狗(dogx);
dog.eat();
dog.say();
//方式3: 静态代理
class 静态代理狗 implements 动物{
private 动物 animal = null;
public 静态代理狗(动物 ani) {
this.animal = animal;
}
@Override
public void eat() {
animal.eat();//不需要改造,调用原有的方法
}
@Override
public void say() {
System.out.println("狗在汪汪汪汪的叫..");//需要改造
}
}
狗 dogx = new 狗();
静态代理狗 dog = new 静态代理狗(dogx);
dog.eat();
dog.say();
/**
* 静态代理与装饰设计模式区别:
* 目的不同:
* 装饰设计模式: 对原有类的方法进行扩展和增强,即可以改造原有类的方法,也可以通过装饰类给原有类增加新的方法.
* 静态代理: 代理类实现原有类的接口,保证代理类拥有原有类的所有方法,目的是为了对原有类的方法进行改造.
*
*/
//方式4: jdk动态代理
final 狗 dog = new 狗();
//创建jdk动态代理对象proxy
动物 proxy = Proxy.newProxyInstance(
dog.getClass().getClassLoader(), //被代理对象的类加载器
dog.getClass().getInterfaces(), //被代理类实现的接口们
new InvocationHandler() { //调用处理器
*//**
* 代理对象调用任何方法时都会执行这个invoke方法
* porxy:代理对象
* method:代理对象当前正在调用的方法,当前正在被调用的方法是eat()和say()
* args:代理对象当前正在调用的方法的参数
*//*
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
if("say".equals(method.getName())){
//如果当前被调用的是say方法,就进行改造
System.out.println("狗在汪汪汪汪的叫...");
return null;
}else{
//如果不是say方法,就使用被代理对象调用原有方法
//此处的invoke(参数1,参数2)方法是Method类中的方法,参数1表示被代理对象,参数2表示当前被调用的方法的参数
//method.invoke(dog, args)等价于dog.eat()
return method.invoke(dog, args);
}
}
});
proxy.eat();
proxy.say();
//方式5: cglib动态代理
//0.准备被代理对象
final 狗 dog = new 狗();
//1.创建增强器
Enhancer enhancer = new Enhancer();
//2.设定代理类需要实现的接口,如果没有接口需要实现,就不设置
enhancer.setInterfaces(dog.getClass().getInterfaces());
//3.设定代理类的父类 -- cglib基于继承实现动态代理,将被代理类作为父类传入
enhancer.setSuperclass(狗.class);
//4.设置回调函数
enhancer.setCallback(new MethodInterceptor(){//方法拦截器
/**
* 代理对象调用任何方法时都会执行这个intercept方法
* porxy:代理对象
* method:代理对象当前正在调用的方法,当前正在被调用的方法是eat()和say()
* args:代理对象当前正在调用的方法的参数
* mp:
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,MethodProxy mp) throws Throwable {
if("say".equals(method.getName())){
System.out.println("狗在汪汪汪汪的叫...");
return null;
}else{
return method.invoke(dog, args);
}
}
});
//5.创建代理对象proxy
狗 proxy = (狗) enhancer.create();
proxy.eat();
proxy.say();
}
}