接口和对象
public interface Person {
void eat();
void sleep();
}
//一定要使用接口
public class PersonImpl implements Person {
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void sleep() {
System.out.println("睡觉");
}
}
代理工厂
1、我自己实现的代理
public class ProxyUtilTest {
public static Person getPersonProxy(Person person){
Person personProxy = new Person() {
@Override
public void eat() {
System.out.println("before:先洗手");
person.eat();
System.out.println("after:刷牙");
}
@Override
public void sleep() {
person.sleep();
}
};
return personProxy;
}
public static void main(String[] args) {
Person person = new PersonImpl();
Person proxy = MineProxyUtil.getPersonProxy(person);
proxy.eat();
proxy.sleep();
}
}
2、jdk方式实现的动态代理
public class ProxyUtil {
private Person person ;
public ProxyUtil(Person person) {
this.person = person;
}
public Object getProxy(){
ClassLoader loader = this.getClass().getClassLoader();
Class[] classes = person.getClass().getInterfaces();
return Proxy.newProxyInstance(loader, classes, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before:先洗手");
Object invoke = method.invoke(person, args);
System.out.println("after:刷牙");
return invoke;
}
});
}
public static void main(String[] args) {
Person person = new PersonImpl();
JDKProxyUtil JDKProxyUtil = new JDKProxyUtil(person);
Person proxy = (Person) JDKProxyUtil.getProxy();
// proxy.eat();
proxy.sleep();
}
}
3、Cglib方式实现的动态代理
package com.zzs;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyUtil implements MethodInterceptor {
//代理方法
public Object createProxy(Object target){
//创建一个动态类对象
Enhancer enhancer = new Enhancer();
//确定需要增强的类,设置其父类
enhancer.setSuperclass(target.getClass());
//添加回调函数
enhancer.setCallback(this);
//返回创建的代理类
return enhancer.create();
}
/**
*proxy CGlib根据指定父类生成的代理对象
*method 拦截的方法
*args 拦截方法的参数数组
*methodProxy 方法的代理对象,用执行父类的方法
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before:先洗手");
Object invokeSuper = methodProxy.invokeSuper(o, objects);
System.out.println("after:刷牙");
return invokeSuper;
}
public static void main(String[] args) {
Person person = new PersonImpl();
CglibProxyUtil cglibProxyUtil =new CglibProxyUtil();
Person proxy = (Person) cglibProxyUtil.createProxy(person);
proxy.eat();
}
}
问题
- jdk方式实现的动态代理,会将接口里面所有的方法都加上前置和后置。
这样子还不如我自己实现的方式灵活?