java常用的设计模式详解:

1.代理模式(JDK的动态代理)

【IDept.java】

​ 这是一个简单的就接口,进行数据的更新

package com.itcloud.pattern.proxy;

public interface IDept {
void update();
}

【DeptImp.java】

​ Dept的实现类

package com.itcloud.pattern.proxy;

public class DeptImpl implements IDept {
@Override
public void update() {
System.out.println("完成核心功能,进行数据的更新操作");
}
}

【InvoProxy.java】

​ 代理类,被代理对象只需要完成核心功能,而其他的功能都由代理对象完成

package com.itcloud.pattern.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class InvoProxy implements InvocationHandler { private Object obj; // 首先要获取代理对象 public Object getProxyInterface(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
} /**
实现的基本步骤
1.获取代理类对象,然后获取其接口
2.生成新的类,实现代理类的接口,这个类其实只是字节码文件
3.在新生成的类中进行代码的执行
*/ @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("数据库开启事物");// 这些事情由代理类完成
try {
return method.invoke(this.obj, args); // 代理类完成核心功能
} catch (Exception e) { } finally {
System.out.println("进行事物的回滚操作");
}
return null;
}
}

【TestDemo.java】

public class TestDemo {
public static void main(String[] args) {
IDept dept = (IDept)new InvoProxy().getProxyInterface(new DeptImpl());
dept.update();
}
}
//测试结果
/*
数据库开启事物
完成核心功能,进行数据的更新操作
进行事物的回滚操作
*/

在代码中我们说过,代理对象会生成一个代理类,那么我们来看一下这个类究竟长什么样

首先在测试类中将字节码写入本地文件

【TestDemo.java】

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

public class TestDemo {
public static void main(String[] args) throws Exception {
IDept dept = (IDept)new InvoProxy().getProxyInterface(new DeptImpl());
dept.update();
byte[] $Proxy0 = ProxyGenerator.generateProxyClass("$Proxy0", new Class<?>[]{IDept.class});
FileOutputStream out = new FileOutputStream("G:\\$Proxy0.class");
out.write($Proxy0);
out.close();
}
}

我们可以在g盘中生成一个$Proxy0.class文件,这个文件就是类的字节码文件,你看不懂我也看不懂这时候需要借用反编译软件(jd-gui-0.3.6),进行反编译

【$Proxy0.class】

import com.itcloud.pattern.proxy.IDept;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0
extends Proxy
implements IDept
{
private static Method m1;
private static Method m2;
private static Method m0;
private static Method m3; public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
} public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
} public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
} public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
} public final Boolean update()
throws
{
try
{
return (Boolean)this.h.invoke(this, m3, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
} static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m3 = Class.forName("com.itcloud.pattern.proxy.IDept").getMethod("update", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}

总结:jdk动态代理必须要有接口

3.cglib代理

cglib中,被代理对象不需要继承相关接口

【pom.xml】文件中添加依赖

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>

【Student.java】

package com.itcloud.pattern.cglib;
public class Student { public void update() {
System.out.println("进行数据的更新操作");
}
}

【CglibProxy.java】

package com.itcloud.pattern.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { //获取代理类的对象
public Object getInstance(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);
enhancer.setSuperclass(clazz);//设置生成代理类的父类
//enhancer.create()这个方法会创建com.itcloud.pattern.cglib.Student$$EnhancerByCGLIB$$4c126679@20e2cbe0代理类,这个代理类是被代理类的子类
return enhancer.create();//enhancer.create() instanceof Student 返回结果true
} /**
*
* @param obj cglib生成的代理类
* @param method 被代理对象中的方法
* @param args 方法的参数
* @param methodProxy 代理方法,即生成代理类中的方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("数据更新前,事物开启"); try {
return methodProxy.invokeSuper(obj, args);//明确调用父类中的方法
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("出现异常,事物回滚,rollback");
}
return null;
}
}

此时我们也可以像JDK动态代理那样对生成的代理类进行字节码反编译。

爱生活爱分享欢迎您的关注与加入自学交流群:461265466

一、spring的成长之路——代理设计模式的更多相关文章

  1. 二·、spring成长之路——委派设计模式和单例设计模式

    3.委派设计模式 设计思想:就是多个类去完成一项的工作,其中一个类去分发任务,其他类做具体的任务,而具体表现是这个委派类的工作,具体过程是被委派类来操作的 [ITask.java]定义工作的统一标准 ...

  2. Spring Boot 成长之路(一) 快速上手

    1.创建工程 利用IntelliJ IDEA新建一个Spring Boot项目的Web工程 2.查看初始化的spring boot项目 工程建好之后会出现如下的目录结构: 值得注意的第一件事是,整个项 ...

  3. Spring知识点总结(四)之SpringAOP基础 - 代理设计模式

        1. 分析程序中存在的问题(高内聚,低耦合)        通过springIOC DI) 以及注解的使用,成功解决了在程序中层与层之间出现的耦合的问题,但是在很多地方仍然存在非该层应该实现的 ...

  4. Spring(八)-- 代理设计模式

    代理设计模式 1:基本概念 2:JDK动态代理 1. 创建接口 2. 创建实现类 3. 创建代理类 /** * jdk动态代理 不能满足 继承父类的情况 * * AnimalProxy 代理类 */ ...

  5. java 成长之路[轉載u]

    分享总结title: java 成长之路tags:grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒闭.这 ...

  6. java 成长之路

    分享总结 title: java 成长之路 tags: grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒 ...

  7. Web前端工程师成长之路

    一.何为Web前端工程师?        前端工程师,也叫Web前端开发工程师.他是随着web发展,细分出来的行业.Web前端开发工程师,主要职责是利用(X)HTML/CSS/JavaScript/D ...

  8. --专访雷果国: 从1.5K到18K 一个程序员的5年成长之路--

    导语:今年三月份,在CSDN博客和新浪微博上有一篇<从1.5K到18K,一个程序员的5年成长之路>被众人分享和传阅,这篇博文首先介绍了作者自学之初薄弱的基础,然后通过流水账形式分享了那个从 ...

  9. linux小白成长之路10————SpringBoot项目部署进阶

    [内容指引] war包部署: jar包部署: 基于Docker云部署. 一.war包部署 通过"云开发"平台初始化的SpringBoot项目默认采用jar形式打包,这也是我们推荐的 ...

随机推荐

  1. ListView属性及divider设置分割线

    给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...

  2. Docker深入浅出系列教程——Docker简介

    我是架构师张飞洪,钻进浩瀚代码,十年有余,人不堪其累,吾不改其乐.如果你和我的看法不一样,请关注我的头条号,我们一起奇闻共赏,疑义相析. 本节属于入门简介,从三个小方面进行简单介绍Docker. Do ...

  3. 【Alpha版本】冲刺阶段 - Day5 - 破浪

    今日进展 袁逸灏:解决音乐播放问题以及跳转问题.(5h) 刘伟康:大致检查了测试规范,参考了其他 alpha 阶段的博客.(1h) 刘先润:解决了敌车与障碍物溢出边界的代码问题,给用户车辆增加了火焰喷 ...

  4. Bate版敏捷冲刺报告--day0

    1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285)  Git链接:https://github.com/WHUSE2017/C-team 2 ...

  5. vue.js下载及安装配置

    环境 Deepin15.4 下载及配置 node下载地址:http://nodejs.cn/download/ 解压到文件夹 /home/maskerk/vue/ 下 设置软连接: $ ln -s / ...

  6. TSP-旅行商问题

    #include <iostream> #include <vector> #include <algorithm> using namespace std; in ...

  7. nyoj 数的长度

    描述 N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)······*2*1.现在你的任务是计算出N!的位数有多少(十进制)?   输入 首行输入n,表示有多少组测试数据(n<1 ...

  8. Ubuntu Desktop 16.04 LTS 下成功配置Jupyter的两个python内核版本(2.7x,3.5x)

    Ubuntu  Desktop 16.04 LTS 安装好系统默认就有python两个不同版本(2.7.12和3.5.2) 现在来熟悉一下jupyter的对python这两个不同python版本的内核 ...

  9. phalcon环境的搭建和dll扩展下载与选择

    phalcon需要下载一个扩展的dll文件才能运行项目 其中需要注意dll放在一个php扩展目录中windows下php/ext/,还需要在两个Php.ini文件中增加扩展说明,一般只需要更改 D:\ ...

  10. href的理解

    您搜索的项目暂未上线,可直接<a style="color: #ff0000;" onclick="onlineTalk();" href="j ...