代理模式实现
这是自己的学习总结,学习网址为:阿里云java高级开发(https://edu.aliyun.com/lesson_36_513).
基础代理设计模式
package model;
import java.lang.reflect.Constructor;
interface ISubject {
/**
* 这个接口只是简单用来实现代理模式的,可以放宽到任意接口
*/
void eat();
}
/**
*
* @author 12872
*
*/
class ResultSubject implements ISubject{
@Override
public void eat() {
System.out.println("吃东西了");
}
}
/**
*
* @author 12872
*
*/
class ProxyFactory {
private ProxyFactory() {
};
@SuppressWarnings("unchecked")
public static <T> T getInstance(String className) {
T t = null;
try {
t = (T) Class.forName(className).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
@SuppressWarnings("unchecked")
public static <T> T getInstance(String className,Object obj) {
T t = null;
try {
//这里需要调用接口来构造,但是实际使用中,一旦接口增加
//这里需要增加的代码量是可想而知的
Constructor<?> cons = Class.forName(className).getConstructor(obj.getClass().getInterfaces()[0]);
t = (T) cons.newInstance(obj);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
}
/**
*
* @author 12872
*
*/
class ProxySubject implements ISubject {
private ISubject subject;
public ProxySubject(ISubject subject) {
this.subject = subject;
}
@Override
public void eat() {
prepare();
this.subject.eat();
clear();
}
public void prepare() {
System.out.println("正在准备食材");
}
public void clear() {
System.out.println("收拾东西");
}
}
/**
*
* @author 12872
*
*/
public class TestDemo {
public static void main(String[] args) {
ISubject subject = ProxyFactory.getInstance("model.ProxySubject", ProxyFactory.getInstance("model.ResultSubject"));
subject.eat();
}
}
可以在这里尽可以需要通过传入一个实例和一个类名来调用,一旦有新的接口,代理模式也将要重新更改。
动态代理设计模式
package model;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface ISubject {
/**
* 这个接口只是简单用来实现代理模式的,可以放宽到任意接口
*/
void eat();
}
/**
*
* @author 12872
*
*/
class ResultSubject implements ISubject{
@Override
public void eat() {
System.out.println("吃东西了");
}
}
/**
* InvocationHandler,只有实现了这个,才能够实现真正的动态代理
*/
package model;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface ISubject {
/**
* 这个接口只是简单用来实现代理模式的,可以放宽到任意接口
*/
void eat();
}
/**
*
* @author 12872
*
*/
class ResultSubject implements ISubject{
@Override
public void eat() {
System.out.println("吃东西了");
}
}
/**
* InvocationHandler,只有实现了这个,才能够实现真正的动态代理
*/
class ProxySubject implements InvocationHandler{
private Object target; //绑定任意的接口对象
/**
* 实现真实对象的绑定处理,同时返回代理对象
* @param target
* @return 返回一个代理对象,根据接口动态定义
*/
public Object bind(String className) {
this.target = Factory.getInstance(className);
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
/**
*
* @author 12872
*
*/
public class TestDemo {
public static void main(String[] args) {
ISubject subject = (ISubject) new ProxySubject().bind("model.ResultSubject");
subject.eat();
}
}
这样子动态代理设计的大概理念就实现了,但是这里还有一些,问题,如果仅仅是这样子的实现,那么和普通的工厂类有什么区别呢,这里将在后续补充。
cglb实现动态代理
这里将实现没有接口的代理设计,但是这里需要使用一个第三方包cglb:下载地址
package model;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.transform.MethodFilter;
class Message{
public void send() {
System.out.println("发送消息");
}
}
class MyProxy implements MethodInterceptor{ //定义一个拦截器
/**
* 真实的代理对象
*/
private Object target;
public MyProxy(Object target) {
this.target = target;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy metProxy) throws Throwable {
this.prepare();
Object ret = method.invoke(this.target, args);
this.over();
return null;
}
public void prepare() {
System.out.println("电脑开机");
}
public void over() {
System.out.println("电脑关闭");
}
}
/**
*
* @author 12872
*
*/
public class ProxyModel {
public static void main(String[] args) {
Message message = new Message();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(message.getClass());
enhancer.setCallback(new MyProxy(message));
Message temp = (Message) enhancer.create();
temp.send();
}
}
这种方式是一种反传统的方式,不推荐使用,只要了解就好