简介
代理模式是结构型模式的一种,在大型项目中十分常见,比如大名鼎鼎的Spring,其AOP的核心就是动态代理,还有Spring data其对数据库操作的底层也是用了动态代理。在生活中,代理模式也十分常见,比如你要去请一个明星做商演,你不会去直接找明显本人而是去找其经纪人,其中经纪人就是充当了代理角色。代理模式分为两种,动态代理和静态代理,下面分别是其代码实现的demo。
静态代理
以明星接商演为例: 1.首先定义明星的接口
public interface Star {
void play();
}
2.定义歌手来实现明星的接口
public class Singer implements Star{
@Override
public void play() {
System.out.println("I will sing");
}
}
3.定义经纪人角色,此角色是代理角色并实现了明星接口,负责明星商演的前后工作。
public class StarProxy implements Star{
private Star star;
public StarProxy(Star star) {
this.star = star;
}
@Override
public void play() {
System.out.println("proxy start interactive");
this.star.play();
System.out.println("proxy accept money");
}
}
4.客户端调用,此时应该去找代理类,而不是明星本人。
public class Test {
public static void main(String[] args) {
Star mike = new Singer();
Star mikeProxy = new StarProxy(mike);
mikeProxy.play();
}
}
动态代理
对于动态代理,有jdk和cglib两种实现方式,JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则代理失效。cglib是针对类来实现代理的,其原理是针对指定的目标实现一个子类,并覆盖其中的方法增强。
JDK动态代理
1.首先定义明星的接口
public interface Star {
void play();
}
2.定义歌手来实现明星的接口
public class Singer implements Star{
@Override
public void play() {
System.out.println("I will sing");
}
}
3.定义经纪人角色,此角色是代理角色并实现了明星接口,负责明星商演的前后工作。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class StarProxy implements InvocationHandler {
private Object object;
public StarProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy start interactive");
method.invoke(object, args);
System.out.println("proxy accept money");
return null;
}
}
4.客户端调用
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
Star mike = new Singer();
InvocationHandler handler = new StarProxy(mike);
Star proxy = (Star) Proxy.newProxyInstance(mike.getClass().getClassLoader(), mike.getClass().getInterfaces(), handler);
proxy.play();
}
}
cglib动态代理
准备工作:cglib的maven坐标
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
1.首先定义明星的接口
public interface Star {
void play();
}
2.定义歌手来实现明星的接口
public class Singer implements Star{
@Override
public void play() {
System.out.println("I will sing");
}
}
3.定义经纪人角色,此角色是代理角色并实现了明星接口,负责明星商演的前后工作。
mport net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class StarProxy implements MethodInterceptor {
private Object target;
public Object getTarget(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("proxy start interactive");
methodProxy.invokeSuper(object, args);
System.out.println("proxy accept money");
return null;
}
}
4.客户端调用
public class Test {
public static void main(String[] args) {
StarProxy proxy = new StarProxy();
Singer mike = new Singer();
Star mikePorxy = (Singer)proxy.getTarget(mike);
mikePorxy.play();
}
}