标签:lang 图像 代理模式 获取 创建 getc 同名 create imp
架构型设计模式成员为其他对象提供一种代理以控制对这个对象的访问
解决问题:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层
接口类
package com.zhunongyun.spring.proxy;
public interface Image {
void display();
void change(String imagePath);
}
--------------------------------------------------
接口的实现类
package com.zhunongyun.spring.proxy;
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("显示图片: " + fileName);
}
@Override
public void change(String imagePath) {
System.out.println("替换图片: " + imagePath);
}
private void loadFromDisk(String fileName){
System.out.println("加载图片: " + fileName);
}
}
-------------------------------------------------------
代理类
package com.zhunongyun.spring.proxy;
public class ProxyImage implements Image{
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
@Override
public void change(String imagePath) {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.change(imagePath);
}
}
---------------------------------------------------
测试类
package com.zhunongyun.spring.proxy;
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("---------------------");
// 图像不需要从磁盘加载
image.display();
}
}
输出结果:
加载图片: test_10mb.jpg
显示图片: test_10mb.jpg
---------------------
显示图片: test_10mb.jpg
每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象
接口类
package com.zhunongyun.spring.proxy.dynamic;
public interface Subject {
int sellBooks();
String speak();
}
---------------------------------------------------------
接口实现类
package com.zhunongyun.spring.proxy.dynamic;
public class RealSubject implements Subject{
@Override
public int sellBooks() {
System.out.println("卖书");
return 1 ;
}
@Override
public String speak() {
System.out.println("说话");
return "张三";
}
}
------------------------------------------------------------------
动态代理类
package com.zhunongyun.study.toalibaba.spring.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 定义一个处理器
*
* @author gnehcgnaw
* @date 2018/11/5 19:26
*/
public class MyInvocationHandler implements InvocationHandler {
/**
* 这其实业务实现类对象,用来调用具体的业务方法
*/
private Object target;
/**
* 绑定业务对象并返回一个代理类
*/
public Object bind(Object target) {
//接收业务实现类对象参数
this.target = target;
//通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
//创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/**
* @param proxy 代理类
* @param method 正在调用的方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result=null;
System.out.println("预处理操作——————");
//调用真正的业务方法
result=method.invoke(target, args);
System.out.println("调用后处理——————");
return result;
}
}
-------------------------------------------------------------------
测试类
package com.zhunongyun.spring.proxy.dynamic;
import java.lang.reflect.Proxy;
/**
* 调用类
* @author gnehcgnaw
* @date 2018/11/7 20:26
*/
public class Client {
public static void main(String[] args) {
//真实对象
Subject realSubject = new RealSubject();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject);
//代理对象
Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, myInvocationHandler);
proxyClass.sellBooks();
proxyClass.speak();
}
}
------------------------------------------------------------------------
输出结果:
预处理操作——————
卖书
调用后处理——————
预处理操作——————
说话
调用后处理——————
操作类
package com.zhunongyun.study.toalibaba.spring.proxy.cglib;
public class BookFacadeImpl {
public void addBook() {
System.out.println("新增图书...");
}
}
-------------------------------------------
CGlib代理类
package com.zhunongyun.study.toalibaba.spring.proxy.cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class BookFacadeCglib implements MethodInterceptor {
/**
* 业务类对象,供代理方法中进行真正的业务方法调用
*/
private Object target;
/**
* 相当于JDK动态代理中的绑定
* @param target
* @return
*/
public Object getInstance(Object target) {
//给业务对象赋值
this.target = target;
//创建加强器,用来创建动态代理类
Enhancer enhancer = new Enhancer();
//为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
enhancer.setSuperclass(this.target.getClass());
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
}
/**
* 实现回调方法
* @param obj
* @param method
* @param args
* @param proxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("预处理——————");
//调用业务类(父类中)的方法
proxy.invokeSuper(obj, args);
System.out.println("调用后操作——————");
return null;
}
}
------------------------------------------------
测试类
package com.zhunongyun.study.toalibaba.spring.proxy.cglib;
public class CglibDemo {
public static void main(String[] args) {
BookFacadeImpl bookFacade = new BookFacadeImpl();
BookFacadeCglib cglib = new BookFacadeCglib();
BookFacadeImpl bookCglib = (BookFacadeImpl) cglib.getInstance(bookFacade);
bookCglib.addBook();
}
}
----------------------------------------
输出结果
预处理——————
新增图书...
调用后操作——————
标签:lang 图像 代理模式 获取 创建 getc 同名 create imp
原文地址:http://blog.51cto.com/huaweicainiao/2327960