1、代理模式
为其他对象提供一种代理以控制对这个对象的访问。
静态代理:(类似于装饰模式),在代理真实对象进行操作时,可以在操作之前与之后添加额外的操作。
实例一:
public interface Sender {
public void send();
}
public class MailSender implements Sender {@Overridepublic void send() {System.out.println(" ~~~~ mailSender ~~~~ ");}}public class StaticProxy implements Sender {private MailSender sender = null;public StaticProxy(final MailSender sender) {this.sender = sender;}@Overridepublic void send() {System.out.println(" ~~~ before send ~~~~");this.sender.send();System.out.println(" ~~~~ after send ~~~~~~");}}
模拟测试:
public class Clinet {
public static void main(final String[] args) {
final StaticProxy sp = new StaticProxy(new MailSender());
sp.send();
}
}
动态代理:(java从1.3开始引入动态代理,但他只能代码实现了一个或者多个接口的类,并不能直接对类进行动态代理)
public interface Sender {
public void send();
}
public class MailSender implements Sender {
@Override
public void send() {
System.out.println(" ~~~~ mailSender ~~~~ ");
}
}
public class DynamicProxy implements InvocationHandler {
private Object object = null;
public DynamicProxy(final Object object) {
this.object = object;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
System.out.println(" ~~~ before send ~~~~");
final Object obj = method.invoke(this.object, args);
System.out.println(" ~~~~ after send ~~~~~~");
return obj;
}
}
模拟使用:
public static void main(final String[] args) {
final Sender sender = new SmsSender();
final InvocationHandler dp = new DynamicProxy(sender);
final Sender senderProxy = (Sender) Proxy.newProxyInstance(sender.getClass().getClassLoader(), sender
.getClass().getInterfaces(), dp);
senderProxy.send();
}
动态代理扩展:如果想对类直接使用动态代理,可以使用CGLIB(Code Generation Library)包。
CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。
Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。
它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。其原理是:生成一个要代理类的子类,子类覆盖要代理的类的所有不是final的方法。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
cglib代码包结构
•core (核心代码) ◦EmitUtils
◦ReflectUtils
◦KeyFactory
◦ClassEmitter/CodeEmitter
◦NamingPolicy/DefaultNamingPolicy
◦GeneratorStrategy/DefaultGeneratorStrategy
◦DebuggingClassWriter
◦ClassGenerator/AbstractClassGenerator
•beans (bean操作类) ◦BeanCopier
◦BulkBean
◦BeanMap
◦ImmutableBean
◦BeanGenerator
•reflect ◦FastClass
•proxy ◦Enhancer
◦CallbackGenerator
◦Callback ■ MethodInterceptor , Dispatcher, LazyLoader , ProxyRefDispatcher , NoOp , FixedValue , InvocationHandler(提供和jdk proxy的功能)
◦CallbackFilter
•util ◦StringSwitcher
◦ParallelSorter
•transform
实例三、(实现对类的代理)
public class Temp {
public void temp() {
System.out.println(" ~~~ temp ~~~~~");
}
}public class CglibProxy implements MethodInterceptor {
public Object createProxy(final Object target) {
final Enhancer enhancer = new Enhancer();
// 设置代理目标
enhancer.setSuperclass(target.getClass());
// 设置回调
enhancer.setCallback(this);
enhancer.setClassLoader(target.getClass().getClassLoader());
return enhancer.create();
}
/**
* @param proxy
* 代理类
* @param method
* 被代理的方法
* @param params
* 该方法的参数数组
* @param methodproxy
* 方法的代理
*/
@Override
public Object intercept(
final Object proxy,
final Method method,
final Object[] params,
final MethodProxy methodProxy) throws Throwable {
System.out.println(" ~~~ before send ~~~~");
final Object o = methodProxy.invokeSuper(proxy, params);
System.out.println(" ~~~~ after send ~~~~~~");
return o;
}
}
模拟调用
public static void main(final String[] args) {
final Temp temp = new Temp();
final CglibProxy cp = new CglibProxy();
final Temp t1 = (Temp) cp.createProxy(temp);
t1.temp();
}