静态代理
大学室友四喜要结婚了,邀请了室友三宝和五福。得到通知怎么办,都需要准备红包啊。既然都需要(虽然都是红包,可能份额不一样),好的,定义一个红包的接口:
/**
* 创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法
* @author Hey Shaw <br>
* 2018年2月12日上午10:25:58
*/
public interface RedEnvelopesInterface {
void slippingSomeoneMoney() ;
}
三宝塞了600进去了
/**
* 创建一个代理类,同时使其也实现RedEnvelopesInterface 这个接口
* @author Hey Shaw<br>
* 2018年2月12日上午10:29:13
*/
public class SanbaoRedEnvelopes implements RedEnvelopesInterface {
@Override
public void slippingSomeoneMoney() {
// TODO Auto-generated method stub
System.out.println("三宝的红包,688块钱!");
}
}
三宝红包准备好了,可是忽然当天有事去不了,这时他想起了让五福帮他顺带一下:
/**
* 代理类实现和被代理类相同的方法,也就是被代理类的任务让代理类顺带完成!
* @author Hey Shaw<br>
* 2018年2月12日上午11:50:52
*/
public class WufuRedEnvelopesStaticsProxy implements RedEnvelopesInterface{
/**
* 拿到三宝的红包 (代理类中持有一个被代理对象的引用)
*/
private RedEnvelopesInterface redEnvelopesInterface = new SanbaoRedEnvelopes() ;
/** 上面的代码可以优化成:
private RedEnvelopesInterface redEnvelopesInterface ;
public WufuRedEnvelopesStaticsProxy (RedEnvelopesInterface redEnvelopesInterface){
this.redEnvelopesInterface = redEnvelopesInterface ;
}
**/
/**
* 在代理类方法中调用该对象的方法
*/
@Override
public void slippingSomeoneMoney() {
// TODO Auto-generated method stub
System.out.println("五福的红包,666块钱 !");
redEnvelopesInterface.slippingSomeoneMoney();
System.out.println("带上自己和三宝的红包出发!");
}
}
将红包交给四喜:
public class LeaveRedEnvelopesToSixi{
public static void main(String[] args) {
// 静态代理
WufuRedEnvelopesStaticsProxy redEnvelopesProxy = new WufuRedEnvelopesStaticsProxy();
/* 优化后调用
WufuRedEnvelopesStaticsProxy redEnvelopesProxy = new WufuRedEnvelopesStaticsProxy(new SanbaoRedEnvelopes());
*/
redEnvelopesProxy.slippingSomeoneMoney();
}
}
动态代理
突遇状况,五福零时有事,也去不了了;这时候三宝想到通过支付宝红包,好了,仍然需要先装好红包,再发给四喜。
沿用:
Interface RedEnvelopesInterface
Class SanbaoRedEnvelopes
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* JDK动态代理(相当于一个代理机构,可以接受很多不同的代理任务)
* @author Hey Shaw<br>
* 2018年2月12日上午10:36:06
*/
public class AlipayDynamicPeoxy implements InvocationHandler {
private Object subject ; // 任意所需代理的任务
public AlipayDynamicPeoxy(Object subject) {
this.subject = subject ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Before invoke " + method.getName());
method.invoke(subject, args);
System.out.println("After invoke " + method.getName());
return null;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class LeaveRedEnvelopesToSixi{
public static void main(String[] args) {
// 动态代理
SanbaoRedEnvelopes sanbaoRedEnvelopes = new SanbaoRedEnvelopes();
InvocationHandler invocationHandler = new AlipayDynamicPeoxy(sanbaoRedEnvelopes) ;
RedEnvelopesInterface redEnvelopesInterface= (RedEnvelopesInterface) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(),
sanbaoRedEnvelopes.getClass().getInterfaces(), invocationHandler);
redEnvelopesInterface.slippingSomeoneMoney();
}
}
静态代理其实不一定需要接口,代理-只需要将三宝需要完成的事代完成即可;JDK动态代理则需要通过接口来实现动态的指定执行哪个代理任务。
一个红包需要封装一个接口,如果在需要给四喜捎点特产,有需要封装一个接口,调用时有需要指向不同的实例,代码量太大。这是就有了CGlib动态代理。
发了一个红包还需要四喜领取才能到账,三宝决定直接转账,直截了当。
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 用于创建增强代理实现了方法拦截
* 在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,
* @author Hey Shaw<br>
* 2018年2月22日上午11:50:19
*/
public class RedEnvelopesMethodInterceptor implements MethodInterceptor {
/**
* Object为由CGLib动态生成的代理类实例
* Method为上文中实体类所调用的被代理的方法引用
* Object[]为参数值列表
* MethodProxy为生成的代理类对方法的代理引用
* return :从代理实例的方法调用返回的值
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Before:"+method.getName());
Object object = methodProxy.invokeSuper(o, objects); // 调用代理示例方法
System.out.println("After:"+method.getName());
return object;
}
}
import net.sf.cglib.proxy.Enhancer;
public class LeaveRedEnvelopesToSixi{
public static void main(String[] args) {
Enhancer enhancer = new Enhancer() ; // CGLIB的字节码增强器
enhancer.setSuperclass(SanbaoRedEnvelopes.class); // 继承被代理类
enhancer.setCallback(new RedEnvelopesMethodInterceptor ()); // 生成代理类对象
SanbaoRedEnvelopes sanbaoRedEnvelopes= (SanbaoRedEnvelopes) enhancer.create() ; // 在调用代理类中方法是会被我们实现的方法拦截器进行拦截
System.out.println("调用时进行方法拦截。。。");
sanbaoRedEnvelopes.slippingSomeoneMoney();
}
}
网友评论