设计模式(12)--Proxy(代理模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入!
1.模式定义:
2.模式特点:
3.使用场景:
4.模式实现:
(1)抽象对象角色:
public abstract class AbstractObject {
//操作
public abstract void operation();
}
(2)目标对象角色:
public class RealObject extends AbstractObject {
@Override
public void operation() {
//一些操作
System.out.println("一些操作");
}
}
(3)代理对象角色:
public class ProxyObject extends AbstractObject{
RealObject realObject = new RealObject();
@Override
public void operation() {
//调用目标对象之前可以做相关操作
System.out.println("before");
realObject.operation();
//调用目标对象之后可以做相关操作
System.out.println("after");
}
}
(4)客户端
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
AbstractObject obj = new ProxyObject();
obj.operation();
}
}
静态代理
(1)接口:IUserDao.java
/**
* 接口
*/
public interface IUserDao {
void save();
}
(2)目标对象:UserDao.java
/**
* 接口实现
* 目标对象
*/
public class UserDao implements IUserDao {
public void save() {
System.out.println("----已经保存数据!----");
}
}
(3)代理对象:UserDaoProxy.java
/**
* 代理对象,静态代理
*/
public class UserDaoProxy implements IUserDao{
//接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target){
this.target=target;
}
public void save() {
System.out.println("开始事务...");
target.save();//执行目标对象的方法
System.out.println("提交事务...");
}
}
(4)测试类:App.java
/**
* 测试类
*/
public class App {
public static void main(String[] args) {
//目标对象
UserDao target = new UserDao();
//代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.save();//执行的是代理的方法
}
}
(5)静态代理总结:
动态代理
(1)动态代理有以下特点:
(2)JDK中生成代理对象的API
(3)代码示例:
[1]代理工厂类:ProxyFactory.java
/**
* 创建动态代理对象
* 动态代理不需要实现接口,但是需要指定接口类型
*/
public class ProxyFactory{
//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//给目标对象生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始事务2");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务2");
return returnValue;
}
}
);
}
}
[2]测试类:App.java
/**
* 测试类
*/
public class App {
public static void main(String[] args) {
// 目标对象
IUserDao target = new UserDao();
// 【原始的类型 class cn.itcast.b_dynamic.UserDao】
System.out.println(target.getClass()); // 给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass()); // 执行方法 【代理对象】
proxy.save();
}
}
(4)总结:
Cglib代理
(1)Cglib子类代理实现方法:
(2)代码示例:
[1]目标对象类:UserDao.java
/**
* 目标对象,没有实现任何接口
*/
public class UserDao {
public void save() {
System.out.println("----已经保存数据!----");
}
}
[2]Cglib代理工厂:ProxyFactory.java
/**
* Cglib子类代理工厂
* 对UserDao在内存中动态构建一个子类对象
*/
public class ProxyFactory implements MethodInterceptor{
//维护目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象创建一个代理对象
public Object getProxyInstance(){
//1.工具类
Enhancer en = new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理对象)
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("开始事务...");
//执行目标对象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务...");
return returnValue;
}
}
[3]测试类:
/**
* 测试类
*/
public class App {
@Test
public void test(){
//目标对象
UserDao target = new UserDao();
//代理对象
UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();
//执行代理对象的方法
proxy.save();
}
}
在Spring的AOP编程中:
5.优缺点:
(1)代理模式的优点:
(2)代理模式的缺点:
6.注意事项
7.应用实例
设计模式(12)--Proxy(代理模式)--结构型的更多相关文章
- 设计模式(十三): Proxy代理模式 -- 结构型模式
设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路 ...
- Proxy代理模式(结构型模式)
1.问题 在面向对象系统中,有些对象由于某种原因(比如创建对象的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给调用者带来麻烦,那么如何在不损失接口透明性的情况下,解决这些麻 ...
- java设计模式之Proxy(代理模式)
java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...
- php设计模式之Proxy(代理模式)和Facade(外观)设计模式
Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...
- Java设计模式:Proxy(代理)模式
概念定义 代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式. 使用代理模式的原因有: 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象, ...
- 设计模式(7)--Bridge(桥接模式)--结构型
1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Impleme ...
- 设计模式(10)--Facade(外观模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使 ...
- 设计模式(9)--Composite(组合模式)--结构型
1.模式定义: 组合模式属于对象的结构模式,有时又叫做“部分——整体”模式.组合模式将对象组织到树结构中,可以用来描述整体与部分的关系.组合模式可以使客户端将单纯元素与复合元素同等看待. 2.模式特点 ...
- 设计模式12: Proxy 代理模式(结构型模式)
Proxy 代理模式(结构型模式) 直接与间接 人们对于复杂的软件系统常常有一种处理手法,即增加一层间接层,从而对系统获得一种更为灵活.满足特定需求的解决方案.如下图,开始时,A需要和B进行3次通信, ...
随机推荐
- DNS 预解析
DNS 解析也是需要时间的,可以通过预解析的方式来预先获得域名所对应的 IP. <link rel="dns-prefetch" href="//yuchengka ...
- 装饰器中的@functools.wraps的作用
def login_required(view_func): @functools.wraps(view_func) def wrapper(*args, **kwargs): ...... retu ...
- Vuex 拾遗
引入Vuex的目的:为众多的Vue组件提供一个全局管理共享组件状态的控制中心,当一个共享状态改变时,能使调用该共享状态的组件得到更新.并且使用Vuex的API,每个共享状态的改变都能被追踪. 组件如何 ...
- POJ 2665
#include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...
- 多线程的实现及常用方法_DAY23
1:多线程(理解) (1)如果一个应用程序有多条执行路径,则被称为多线程程序. 进程:正在执行的程序. 线程:程序的执行路径,执行单元. 单线程:如果一个应用程序只有一条执行路径,则被称为单线程程序. ...
- Java生成某段时间内的随机时间
上代码: import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { /** * 生成随机时间 ...
- dubbo-001--前言
1,前言: 第一次了解dubbo是在15年刚工作的时候在瑞友,项目是给凯撒旅游公司签证部做一个签证系统,项目需要调用一些凯撒的方法,比如权限.部门信息,跟签证相关的一些如签证国家城市.领区啥玩意的,等 ...
- SHELL脚本编程的常识和VI常用技巧
来源:http://mprc.pku.edu.cn/mentors/training/TrainingCourses/material/ShellProgramming.HTM#_Toc3751808 ...
- Jmeter报错之jmeter.gui.action.ActionRouter: Error processing gui.action.Start@1b7c473a java.lang.ArrayIndexOutOfBoundsException
一个使用了很久的Jmeter脚本,运行时Jmeter的UI界面上点击绿色按钮后,完全无反应,只有log报错,如下: 2017/06/28 14:29:23 ERROR - jmeter.gui.act ...
- lucene 初探 - 查询
lucene初探, 是为了后面solr做准备的. 如果跳过lucene, 直接去看solr, 估计有点懵. 由于时间的关系, lucene查询方法也有多个, 所以单独出来. 一. 精确查询 /** * ...