cglib

学习Java代理模式,这一篇够用了

我是研究僧i 提交于 2020-08-14 11:01:45
这篇代理模式的讲解,会通过其概念、特点,最后通过编码实现每个代理模式的使用场景。 什么是代理模式 代理模式是Java语言中一种编程的设计模式。包括两个重要角色:委托类和代理类。代理类可以在调用委托类同时,对委托类的现有功能的基础之上进行扩展。 如何理解这个模式呢?用日常生活中常见的事情通俗的表述就是: 房东把自己需要被出租的房子,交给房产中介,让其帮忙打理后续包括带租客看房、签合同等繁杂流程,房东只需最后通过房子获取利益就行。这个例子中,房东就是委托类,房产中介就是代理类。 在Java开发中,代理分为静态代理和动态代理。 动态代理又分为jdk动态代理和cglib动态代理。 静态代理、动态代理的特点 静态代理 优点:能做到在不修改委托类代码的前提下,还能通过代理类添加新的功能。 缺点:委托类和代理类都是实现了上级父类的接口,一旦父类接口代码变动,委托类和代理类都要维护代码。 动态代理 动态代理中的jdk代理可以解决静态代理中的那个缺点。jdk动态代理的代理类不需要实现父级的接口,但是委托类需要实现父级的接口。 它通过Java反射机制动态生成代理类,不仅简化了编程的工作,并且提高了软件系统的可扩展性。 上面的静态代理和jdk动态代理都必须让委托类实现父级的接口,假如委托类不去实现任何接口,它们两个代理模式就用不了,所以此时cglib动态代理就上位了。 编码实现静态代理 父类的接口 /*

代理,注解,接口和实现类的小测验

三世轮回 提交于 2020-08-14 05:06:27
* retention : 保留 * policy : 策略 ps : 简单测试了一下手写代理,jdk动态代理,和cglib动态代理,根据其不同的结果分析其原理 一:测试目的 主要想看一下不同的代理模式对于目标类中方法上注解的读取能力 二:代理简述 jdk动态代理:只针对接口操作 cglib动态代理:既可以为没有实现接口的类去做代理,也可以为实现接口的类去做代理 三:代码准备 1)自定义注解 设置保留策略为运行期 注解中只定义一个数组 当属性名为 value 时,注解中可以省略不写 @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { String[] value(); } 2)接口 public interface Service { void eat(); } 3)实现类 在eat()方法上添加自定义注解 public class ServiceImpl implements Service { @Override @MyAnno({"jim","tom"}) public void eat() { System.out.println("eat ... "); } } 三:测试实例 1)手写代理模式 public class AnnoTest implements Service{ @MyAnno({

Spring AOP里的静态代理和动态代理,你真的了解嘛?

霸气de小男生 提交于 2020-08-14 01:42:48
什么是代理?   为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间 什么是静态代理?   由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在   通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的。 优点   代理使客户端不需要知道实现类是什么,怎么做,而客户端只需知道代理即可   方便增加功能,扩展业务逻辑 缺点   代理类中常出现大量冗余的代码,非常不利于扩展和维护   如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度 案例演示 PayService.java( 接口 ) package net.cybclass.sp.proxy; public interface PayService { /** * 支付回调 * @param outTradeNo 订单号 * @return */ String callback(String outTradeNo); /** * 下单 * @param userId 用户id *

Java代码精简之道

痴心易碎 提交于 2020-08-13 09:37:06
前言 古语有云: 道为术之灵,术为道之体;以道统术,以术得道。 其中:“道”指“规律、道理、理论”,“术”指“方法、技巧、技术”。意思是:“道”是“术”的灵魂,“术”是“道”的肉体;可以用“道”来统管“术”,也可以从“术”中获得“道”。 在拜读大佬“孤尽”的文章《 Code Review是苦涩但有意思的修行 》时,感受最深的一句话就是:“优质的代码一定是 少即是多 的精兵原则”,这就是大佬的代码精简之“道”。 工匠追求“术”到极致,其实就是在寻“道”,且离悟“道”也就不远了,亦或是已经得道,这就是“工匠精神”——一种追求“以术得道”的精神。 如果一个工匠只满足于“术”,不能追求“术”到极致去悟“道”,那只是一个靠“术”养家糊口的工匠而已。作者根据多年来的实践探索,总结了大量的Java代码精简之“术”,试图阐述出心中的Java代码精简之“道”。 1.利用语法 1.1.利用三元表达式 普通: String title; if (isMember(phone)) { title = "会员"; } else { title = "游客"; } 精简: String title = isMember(phone) ? "会员" : "游客"; 注意:对于包装类型的算术计算,需要注意避免拆包时的空指针问题。 1.2.利用for-each语句 从Java 5起,提供了for-each循环

Java 线程通信之 wait/notify 机制

拟墨画扇 提交于 2020-08-13 03:46:26
前言 Java 线程通信是将多个独立的线程个体进行关联处理,使得线程与线程之间能进行相互通信。比如线程 A 修改了对象的值,然后通知给线程 B,使线程 B 能够知道线程 A 修改的值,这就是线程通信。 wait/notify 机制 一个线程调用 Object 的 wait() 方法,使其线程被阻塞;另一线程调用 Object 的 notify()/notifyAll() 方法,wait() 阻塞的线程继续执行。 wai/notify 方法 方法 说明 wait() 当前线程被阻塞,线程进入 WAITING 状态 wait(long) 设置线程阻塞时长,线程会进入 TIMED_WAITING 状态。如果设置时间内(毫秒)没有通知,则超时返回 wait(long, int) 纳秒级别的线程阻塞时长设置 notify() 通知同一个对象上已执行 wait() 方法且获得对象锁的等待线程 notifyAll() 通知同一对象上所有等待的线程 实现 wait/notify 机制的条件: 调用 wait 线程和 notify 线程必须拥有相同对象锁。 wait() 方法和 notify()/notifyAll() 方法必须在 Synchronized 方法或代码块中。 由于 wait/notify 方法是定义在 java.lang.Object 中,所以在任何 Java 对象上都可以使用。

mybatis源码分析——数据的绑定

大城市里の小女人 提交于 2020-08-12 15:15:35
  orm的演进过程,jdbc——ibatis——mybatis,jdbc最基础的访问数据库的方式,ibatis基于jdbc进行了封装,程序员 可以直接在xml里面写sql,通过调用dao中的方法执行数据库的操作,mybatis省略了dao的步骤,只需要mapper中的方法与 mapper.xml中的sqlId映射上,就可以直接调用。   1:通过mybatis源码看一下mybatis的实现原理 实现原理就是动态代理,动态代理有两种,jdk代理和cglib代理,jdk代理必须基于接口,在内存中动态生成接口的子类来实现 在上一节中,解析mapper.xml的时候会解析命名空间 public void parse() { if (!configuration.isResourceLoaded(resource)) { // 解析sql,生成mapperStatement configurationElement(parser.evalNode("/mapper")); configuration.addLoadedResource(resource); // 解析命名空间,绑定代理工厂 bindMapperForNamespace(); } parsePendingResultMaps(); parsePendingChacheRefs();

代理模式

旧巷老猫 提交于 2020-08-12 06:45:12
一 代理模式简介 代理(Proxy)是一种设计模式 提供了对目标对象另外的访问方式 代理对象代理目标对象 达到增强目标对象功能的目的 二 静态代理 需要定义接口或者父类 代理对象与目标对象一起实现相同接口或者继承相同父类 优点: 在不修改目标对象的功能前提下 对目标功能扩展 缺点: 因为代理对象需要与目标对象一起实现相同接口或者继承相同父类 所以会有很多代理类 导致类太多 同时 如果接口增加方法 代理对象与目标对象都要维护 1. 接口 /** * 接口 * Created by Hy on 2020/7/10. */ public interface IUserService { void insertUser(); String deleteUser( int id); } 2. 目标对象 /** * 目标对象 * Created by Hy on 2020/7/10. */ public class UserService implements IUserService { @Override public void insertUser() { System.out.println( "insert ok" ); } @Override public String deleteUser( int id) { System.out.println( "delete... ...

代理模式

强颜欢笑 提交于 2020-08-11 15:00:19
一 代理模式简介 代理(Proxy)是一种设计模式 提供了对目标对象另外的访问方式 代理对象代理目标对象 达到增强目标对象功能的目的 二 静态代理 需要定义接口或者父类 代理对象与目标对象一起实现相同接口或者继承相同父类 优点: 在不修改目标对象的功能前提下 对目标功能扩展 缺点: 因为代理对象需要与目标对象一起实现相同接口或者继承相同父类 所以会有很多代理类 导致类太多 同时 如果接口增加方法 代理对象与目标对象都要维护 1. 接口 /** * 接口 * Created by Hy on 2020/7/10. */ public interface IUserService { void insertUser(); String deleteUser( int id); } 2. 目标对象 /** * 目标对象 * Created by Hy on 2020/7/10. */ public class UserService implements IUserService { @Override public void insertUser() { System.out.println( "insert ok" ); } @Override public String deleteUser( int id) { System.out.println( "delete... ...

设计模式在 Spring 中的应用解析(建议收藏系列)

橙三吉。 提交于 2020-08-11 13:34:21
设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记只是一直没有记忆 。 今天,就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念,才能在工作学习 中运用到“无形”。 Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行内典范 。 spring中常用的设计模式达到九种,我们一一举例 : 第一种:简单工厂 又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象 ,但是否是在传入 参数后创建还是传入参数前创建这个要根据具体情况来定。 如下配置,就是在 HelloItxxz 类中创建一个 itxxzBean 。 第二种:工厂方法(Factory Method) 通常由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式, 即应用程序将对象的创建及初始化职责交给工厂对象。 一般情况下,应用程序有自己的工厂对象来创建bean. 如果将应用程序自己的工厂对象交给Spring管理,那么Spring管理的就不是普通的bean,而是工厂Bean。

AOP原理解析

穿精又带淫゛_ 提交于 2020-08-11 04:54:50
MainConfigOfAOP.class /** * AOP: * 指在程序运行期间动态的将某段代码切入到指定方法指定位置运行的编程方式 * 1. 导入AOP模块:Spring aop,(Spring-aspects) * 2. 定义一个业务逻辑类(MathCalculator),在业务逻辑运行时将日志进行打印(方法之前、方法运行、方法之后、方法异常) * 3. 定义一个日志切面(LogAspect),切面里的方法要动态感知MathCalculator.div运行到哪 * 通知方法: * 前置通知(@Before):logStart:在目标方法(div)运行之前运行 * 后置通知(@After):logEnd:在目标方法(div)运行之后运行(正常结束和异常结束) * 返回通知(@Returning):logEnd:在目标方法(div)返回之后运行 * 异常通知(@AfterThrowing):logEnd:在目标方法(div)异常之后运行 * 环绕通知(@Around):动态代理,手动控制目标方法运行(joinPoint.proceed()) * 4. 给切面的方法标注何时何地运行 * 5. 将切面类和业务逻辑类都加入到容器中 * 6. 必须告诉Spring容器哪个类是切面类,在切面类加@Aspect注解 * 7. 使用@EnableAspectJAutoProxy注解开启 *