Java中代理和装饰者模式的区别
装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用;
装饰模式为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能
简而言之,装饰者是指的是自身,对功能的增强,而另一种是调用接口,实现对代理对象的控制
在Spring AOP中,主要使用了两种代理方式:jdkProxy、cjlibProxy
cjlibProxy:
package com.cjlib; import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /**
* @author weining
* @date 2019/10/31 8:45
*/
public class CglibProxyExample implements MethodInterceptor { public Object getProxy(Class cls) {
//CGLIB enhancer 增强类对象
Enhancer enhancer = new Enhancer(); //设置增强类型
enhancer.setSuperclass(cls); //定义逻辑对象,要求实现当前对象实现MethodInterceptor方法
enhancer.setCallback(this); //返回代理对象
return enhancer.create();
} /**
* 代理逻辑方法
*
* @param o 代理对象
* @param method 方法
* @param objects 方法参数
* @param methodProxy 方法代理
* @return 代理逻辑返回
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("调用真是对象之前");
Object invokeSuper = methodProxy.invokeSuper(o, objects);
System.out.println("调用真是对象之后"); return invokeSuper;
}
}
测试方法:
package com.cjlib; import com.jdk.HelloWorld;
import com.jdk.impl.HelloWorldImpl; /**
* @author weining
* @date 2019/10/31 9:03
*/
public class testCGLIBProxy {
public static void main(String[] args) {
CglibProxyExample cglibProxyExample = new CglibProxyExample();
HelloWorld helloWorld = (HelloWorldImpl) cglibProxyExample.getProxy(HelloWorldImpl.class);
helloWorld.sayHello();
}
}

jdkProxy:
package com.jdk; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author weining
* @date 2019/10/31 8:29
* 在jdk动态代理时 必须要实现InvocationHandler接口
* 自动生成接口中的invoke方法
*/
public class JdkProxyExample implements InvocationHandler { private Object target = null; public Object bind(Object target){
this.target = target;
/*
三个属性分别是:类加载器,把生成的动态代理对象挂在哪个接口之上,定义实现方法逻辑的代理类
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
} /**
* invoke可以实现代理对象
* @param proxy bind 返回的对象
* @param method 当前调度的方法
* @param args 调度方法的参数
* @return 代理的结果返回
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调用真实对象的服务");
Object obj=method.invoke(target,args);
System.out.println("在调用真实对象之后的服务");
return obj;
}
}
这时,创建一个HelloWorld接口:
package com.jdk; /**
* @author weining
* @date 2019/10/31 8:27
*/
public interface HelloWorld {
public void sayHello();
}
创建接口的实现类:
package com.jdk.impl; import com.jdk.HelloWorld; /**
* @author weining
* @date 2019/10/31 8:27
*/
public class HelloWorldImpl implements HelloWorld {
public void sayHello() {
System.out.println("Hello,World!");
}
}
最后调用测试方法:
package com.jdk; import com.jdk.impl.HelloWorldImpl; /**
* @author weining
* @date 2019/10/31 8:40
*/
public class test {
public static void main(String[] args) {
JdkProxyExample jdkProxyExample = new JdkProxyExample(); HelloWorld proxy = (HelloWorld) jdkProxyExample.bind(new HelloWorldImpl());
proxy.sayHello(); }
}

两者的区别
1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,
并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,
对于final类或方法,是无法继承的。
装饰者模式:
//装饰器模式
public class Decorator implements Component{
private Component component;
public Decorator(Component component){
this.component = component
}
public void operation(){
….
component.operation();
….
}
}
//装饰器的客户
public class Client{
public static void main(String[] args){
//客户指定了装饰者需要装饰的是哪一个类
Component component = new Decorator(new ConcreteComponent());
…
}
}
Java中代理和装饰者模式的区别的更多相关文章
- [转载]Java中继承、装饰者模式和代理模式的区别
[转载]Java中继承.装饰者模式和代理模式的区别 这是我在学Java Web时穿插学习Java设计模式的笔记 我就不转载原文了,直接指路好了: 装饰者模式和继承的区别: https://blog.c ...
- JAVA设计模式之【装饰者模式】
JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...
- Java中public,private,protected,和默认的区别
Java中public,private,protected,和默认的区别 1.private修饰词,表示成员是私有的,只有自身可以访问: 2.protected,表示受保护权限,体现在继承,即子类可以 ...
- 【Java学习笔记之二十九】Java中的"equals"和"=="的用法及区别
Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: String str1 = new String(" ...
- java中public与private还有protect的区别
java中public与private还有protect的区别 总是忘记.
- Java中的基本类型和引用类型变量的区别
Java中的基本类型和引用类型变量的区别 学了一年多,说实话你要我说这些东西我是真说不出来是啥意思 基本类型: 基本类型自然不用说了,它的值就是一个数字,一个字符或一个布尔值. 引用类型: ...
- JAVA中局部变量 和 成员变量有哪些区别
JAVA中局部变量 和 成员变量有哪些区别 1.定义的位置不一样<重点>***局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中 2.作用范围不一样<重点>***局部 ...
- java 中,for、for-each、iterator 区别
java 中,for.for-each.iterator 区别: 无论是在数组中还是在集合中,for-Each加强型for循环都是它们各自的普通for循环的一种"简写方式",即两者 ...
- java中String new和直接赋值的区别
Java中String new和直接赋值的区别 对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才 ...
随机推荐
- Method Not Allowed (GET): /boxuegos/index/ 错误
1,Method Not Allowed (GET) 请求方法不被允许, 错误原因:我调用的是index这个方法,但是我上面定义了一个空的子路由,所以页面加载不了,控制台出现Method Not Al ...
- 12 Zabbix4.4.0系统sendEmail邮件报警优化
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 12 Zabbix4.4.0系统sendEmail邮件报警优化 接上一章节 Zabbix4.4. ...
- Matplotlib 设置
# 导入相关模块 import matplotlib.pyplot as plt import numpy as np 设置 figure Matplotlib 绘制的图形都在一个默认的 figure ...
- zookeeper能干啥
在Zookeeper的官网上有这么一句话:ZooKeeper is a centralized service for maintaining configuration information, n ...
- p4141(消失之物)
题目描述 ftiasch 有 N 个物品, 体积分别是 W1, W2, …, WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N – 1 物品装满容积为 x 的背包,有几种方法呢?” ...
- 代码托管服务平台GitHub
GitHub 可以托管各种 git 库,并提供一个 Web 界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简 ...
- 基于docker搭建Jenkins+Gitlab+Harbor+Rancher架构实现CI/CD操作(续)
说明:前期的安装,请转向https://www.cnblogs.com/lq-93/p/11824039.html (4).查看gitlab镜像是否启动成功 docker inspect 容器id ...
- SpringBoot 源码解析 (三)----- Spring Boot 精髓:启动时初始化数据
在我们用 springboot 搭建项目的时候,有时候会碰到在项目启动时初始化一些操作的需求 ,针对这种需求 spring boot为我们提供了以下几种方案供我们选择: ApplicationRunn ...
- 爬虫实践--CBA历年比赛数据
闲来无聊,刚好有个朋友来问爬虫的事情,说起来了CBA这两年的比赛数据,做个分析,再来个大数据啥的.来了兴趣,果然搞起来,下面分享一下爬虫的思路. 1.选取数据源 这里我并不懂CBA,数据源选的是国内某 ...
- vue 前端处理监听关键字搜索
根据组件的业务需要,有时候搜索是把关键字返回给后台,后台处理后再把数据返回给前端渲染(多次请求服务器):有时候是前端把页面的数据全部获取下来,前端处理关键字的搜索(影响页面加载) 我这个文章是介绍第二 ...