代理,这里讲三种代理实现方式
1.静态代理
静态代理是基于接口实现方式实现代理操作
类似于 某个公司需要找明星代言产品,那么在找指定的明星的时候,是不会直接找到其明星本人,而是找他的经纪人或者经济公司,那么这个经纪人或者经济公司实际上就是该明星的代理操作,最终做事情的还是明星,代理只是帮明星做了前置或者后置的一些工作
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:44
* @Version 1.0
* 接口 功能 描述
**/
public interface ShowTime {
void sing();
void eat();
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:45
* @Version 1.0
* 明星 实现 接口 他真正要做的事情
**/
public class Star implements ShowTime {
public void eat() {
System.out.println("歌星一起吃饭");
}
public void sing() {
System.out.println("歌星唱歌....");
}
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:43
* @Version 1.0
* 代理类 经纪人或者经济公司
* 必须跟代理目标实现同一接口
**/
public class Company implements ShowTime{
//代理目标
private Star star = new Star();
public void sing() {
System.out.println("提前预约谈合作");
star.sing();
System.out.println("演出结束,请付钱");
}
public void eat() {
System.out.println("提前预约吃饭");
star.eat();
System.out.println("吃完饭,请给钱");
}
}
//测试类
public class Test {
public static void main(String[] args) {
Company company = new Company();
//最终执行的是 代理类 [明星的] 操作 代理只是做了前置 后置工作
company.sing();
}
}
缺点是:如果接口发生变化,代理类和目标代理对象类 必须 修改
2.动态代理[jdk]
动态代理实现方式 是由JDK API 来实现,此时,可以不用考虑接口是否有改动操作
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:44
* @Version 1.0
* 接口 功能 描述
**/
public interface ShowTime {
void sing();
void eat();
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:45
* @Version 1.0
* 目标对象 实现接口
**/
public class Star implements ShowTime {
public void eat() {
System.out.println("请歌星出场吃饭");
}
public void sing() {
System.out.println("歌星唱歌....");
}
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:43
* @Version 1.0
* 代理类 实现接口 InvocationHandler
**/
public class Company implements InvocationHandler {
//代理目标对象
private Star star = new Star();
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("预约安排出场");
//执行目标对象方法
Object invoke = method.invoke(star, args);
System.out.println("出场结束 请给钱了");
return invoke;
}
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:50
* @Version 1.0
* 测试类
**/
public class Test {
public static void main(String[] args) {
Company company = new Company();
//通过 JDK API 提供的 方法 操作 获取代理对象
ShowTime proxy =(ShowTime) Proxy.newProxyInstance(
Test.class.getClassLoader(), //类加载器
new Class[]{ShowTime.class}, //实现的接口数组
company);//代理对象
//执行方法
proxy.sing();
//输出 其对象 class信息
System.out.println( proxy.getClass() );
}
}
特点是必须有接口和子实现
3.cglib代理 {子类代理 不需要实现接口}
导入jar包
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:45
* @Version 1.0
* 目标对象
**/
public class Star {
public void eat() {
System.out.println("歌星出场吃饭");
}
public void sing() {
System.out.println("歌星唱歌....");
}
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:43
* @Version 1.0
* 代理对象
**/
public class Company implements MethodInterceptor {
/**
*
* @param o 代理对象
* @param method 方法
* @param objects 参数
* @param methodProxy 代理方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("预约时间");
//调用子类重写的方法 invoke
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("演出完毕请付费");
return invoke;
}
}
/**
* @Description
* @Author xz
* @Date 2019/7/18 21:50
* @Version 1.0
* 测试类
**/
public class Test {
public static void main(String[] args) {
//字节码生成工具类
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(Star.class);
//设置回调函数
enhancer.setCallback(new Company());
//创建子类对象
Star o = (Star)enhancer.create();
o.eat();
//输出 代理对象 class信息
System.out.println( o.getClass() );
}
}
特点:可以不用实现接口