代理模式(静态代理)
- 普通代理模式的核心就是,被代理对象和代理对象(共属一个接口),被代理对象要执行的操作由代理对象完成(此时被代理者需要手动new出来,再传递给代理者)。
- 普通代理模式还可以拓展,即调用时只见代理者而不见被代理者(更符合逻辑),被代理者的new由代理者完成。
普通代理 + 拓展
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c1962e9617e3fe42c13124b612acdfe4.png)
真实对象GamePlayer
public class GamePlayer implements IGamePlayer {
private String name = "";
public GamePlayer(String _name){
this.name = _name;
}
public GamePlayer(IGamePlayer _gamePlayer,String _name){
if (_gamePlayer == null) throw new RuntimeException("不能创建真实角色");
else this.name = _name;
}
@Override
public void login(String user, String password) {
System.out.println("登录名为:" + user + "的用户" + this.name + "登录成功!");
}
@Override
public void killBoss() {
System.out.println(this.name + "打机械牛");
}
@Override
public void upgrade() {
System.out.println(this.name + "升了一级");
}
}
代理对象
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
public GamePlayerProxy(String name){
try {
gamePlayer = new GamePlayer(this,name);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
this.gamePlayer.killBoss();
}
}
入口类
public class ProxyMain {
public static void main(String[] args) {
manual();
proxy();
}
public static void proxy(){
GamePlayerProxy playerProxy = new GamePlayerProxy("Devilvan");
playerProxy.login("Devilvan","123456");
playerProxy.killBoss();
playerProxy.upgrade();
}
public static void manual(){
GamePlayerProxy player = new GamePlayerProxy("Devilvan");
player.login("Devilvan","123456");
player.killBoss();
player.upgrade();
}
}
结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c24fc3e8f640bd3e5bbdd9d393f8e551.png)
代理模式(强制代理)
- 必须通过真实角色获取代理角色才可以访问
- 例如:A找B办事,但是B让A去找代理人C,即A必须找到B指定的C才行。不经过B或不找C而去找其他代理D也是不行的
强制代理
接口
public interface IGamePlayer2 {
public void login(String user,String password);
public void killBoss();
public void upgrade();
public IGamePlayer2 getProxy();
}
真实角色
public class GamePlayer2 implements IGamePlayer2 {
private String name = "";
private IGamePlayer2 proxy = null;
public GamePlayer2(String name){
this.name = name;
}
public IGamePlayer2 getProxy(){
this.proxy = new GamePlayerProxy2(this);
return this.proxy;
}
private boolean isProxy(){
return this.proxy != null;
}
@Override
public void login(String user, String password) {
if (isProxy()){
System.out.println("登录名为:" + user + "的用户" + this.name + "登录成功!");
} else {
System.out.println("请使用指定的代理服务器");
}
}
@Override
public void killBoss() {
if (isProxy()){
System.out.println(this.name + "打机械牛");
} else {
System.out.println("请使用指定的代理服务器");
}
}
@Override
public void upgrade() {
if (isProxy()){
System.out.println(this.name + "升了一级");
} else {
System.out.println("请使用指定的代理服务器");
}
}
}
代理对象
public class GamePlayerProxy2 implements IGamePlayer2 {
private IGamePlayer2 gamePlayer = null;
public GamePlayerProxy2(IGamePlayer2 _gamePlayer){
this.gamePlayer = _gamePlayer;
}
@Override
public IGamePlayer2 getProxy() {
return this;
}
@Override
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
入口类
public class Proxy2Main {
public static void main(String[] args) {
visitReal();
visitProxy();
forceProxy();
}
public static void forceProxy(){
IGamePlayer2 evad = new GamePlayer2("Evad").getProxy();
evad.login("Evad","loop");
evad.killBoss();
evad.upgrade();
}
public static void visitProxy(){
GamePlayerProxy2 lisi = new GamePlayerProxy2(new GamePlayer2("Lisi"));
lisi.login("lisi","123124");
lisi.killBoss();
lisi.upgrade();
}
public static void visitReal(){
GamePlayer2 zs = new GamePlayer2("张三");
zs.login("张三","233939");
zs.killBoss();
zs.upgrade();
}
}
结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e2bfc0616df5a7bd189de3c417edf815.png)
代理模式(代理的个性)
- 代理类除了实现与真实对象相同的接口外,还能实现其他的业务(接口),满足更多的需求
代理的个性
代理类个性接口
public interface IProxy {
public void count();
}
代理类
public class GamePlayerProxy2 implements IGamePlayer2, IProxy {
private IGamePlayer2 gamePlayer = null;
public GamePlayerProxy2(IGamePlayer2 _gamePlayer){
this.gamePlayer = _gamePlayer;
}
@Override
public IGamePlayer2 getProxy() {
return this;
}
@Override
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
this.gamePlayer.upgrade();
this.count();
}
@Override
public void count() {
System.out.println("升一级+5元");
}
}
代理模式(动态代理)
- 动态代理在实现阶段不用关心代理对象是谁,而在运行阶段才指定代理的是哪个对象
- 动态代理需要实现InvocationHandler接口,作用相当于代理类
动态代理
代理类
public class GamePlayInvocationHandler implements InvocationHandler {
Class<?> clz = null;
Object obj = null;
public GamePlayInvocationHandler(Object _obj){
this.obj = _obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(obj, args);
if (method.getName().equalsIgnoreCase("login")){
System.out.println("有人在使用我的账号!");
}
return result;
}
}
入口类
public class InvocationHandlerMain {
public static void main(String[] args) {
GamePlayer player = new GamePlayer("Van DarkHomle");
GamePlayInvocationHandler handler = new GamePlayInvocationHandler(player);
ClassLoader cl = player.getClass().getClassLoader();
IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, new Class[]{IGamePlayer.class}, handler);
proxy.login("Van DarkHomle","What you see");
proxy.killBoss();
proxy.upgrade();
}
}
结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/97b247a0779e31ae104715698c3d684c.png)
代理模式(动态代理通用模型)
- 核心部分为自定义的Handler、Proxy和通知
- 其中proxy还可以根据业务需要进行定制
动态代理通用模型
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b0dd87f3b1eefd389aad6f71c2c120b4.png)
Handler
public class MyInvocationHandler implements InvocationHandler {
private Object target = null;
public MyInvocationHandler(Object _obj){
this.target = _obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
Proxy及其子类
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
(new BeforeAdvice()).exec();
return (T) Proxy.newProxyInstance(loader, interfaces, h);
}
}
public class SubjectDynamicProxy extends DynamicProxy{
public static <T> T newProxyInstance(Subject subject){
ClassLoader classLoader = subject.getClass().getClassLoader();
Class<?>[] interfaces = subject.getClass().getInterfaces();
InvocationHandler handler = new MyInvocationHandler(subject);
return newProxyInstance(classLoader,interfaces,handler);
}
}
业务类(抽象主题)及其实现类
public interface Subject {
public void doSomething(String str);
}
public class RealSubject implements Subject {
@Override
public void doSomething(String str) {
System.out.println("do something ---------> " + str);
}
}
AOP通知类及其实现类
public interface IAdvice {
public void exec();
}
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
System.out.println("这里是前置通知");
}
}
入口类
public class GeneralDynamicProxyMain {
public static void main(String[] args) {
Subject subject = new RealSubject();
InvocationHandler handler = new MyInvocationHandler(subject);
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
proxy.doSomething("Finish..");
System.out.println("------------具体业务的动态代理------------");
Subject proxy2 = SubjectDynamicProxy.<Subject>newProxyInstance(subject);
proxy2.doSomething("Finish2...");
}
}
结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/97878c713fbbcaa4eb7b9c23ec12e466.png)