javassist

Javassist: creating an interface that extends another interface with generics

痞子三分冷 提交于 2019-11-30 07:42:36
问题 I am using javassist in a project and I need to create the following interface at runtime: package com.example; import org.springframework.data.repository.CrudRepository; import com.example.Cat; public interface CatRepository extends CrudRepository<Cat, Long> {} While I had no problem creating the interface CatRepository extending CrudRepository , I do not understand (from the docs and from looking at the source code), how to specify com.example.Cat and java.lang.Long as generics types to the

【Java设计模式】之代理模式

大憨熊 提交于 2019-11-30 07:13:52
代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。 为什么要采用这种间接的形式来调用对象呢?一般是因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。 代理模式的UML图 从UML图中,可以看出代理类与真正实现的类都是继承了抽象的主题类,这样的好处在于代理类可以与实际的类有相同的方法,可以保证客户端使用的透明性。 代理模式的实现 代理模式可以有两种实现的方式,一种是静态代理类,另一种是各大框架都喜欢的动态代理。下面我们主要讲解一下这两种代理模式 1、静态代理 我们先看针对上面UML实现的例子,再看静态代理的特点。 Subject接口的实现 public interface Subject { void visit(); } 实现了Subject接口的两个类: public class RealSubject implements Subject { private String name = "byhieg"; @Override public void visit() { System.out.println(name); } } public class ProxySubject implements Subject{ private Subject

dubbo源码理解(1)启动初始化与bean加载

旧巷老猫 提交于 2019-11-30 02:51:21
今天看了一些博文,都是关于dubbo源码解析方面的。觉得有必要记一下。 问题1:spring 如何注入dubbo 的?或者说怎么集成dubbo 的,或者说 dubbo启动时怎么启动spring的? 1、首先想要实现 在spring 中 发挥某框架的功能,就必须将该框架注入到springBean 中。 2、dubbo 中 dubbo-container-spring 模块,类 spirngContainer 里面的start方法实现了这功能。 3、上述的start方法 由dubbo 的Main方法调用。。。 4、start方法执行时 会调用spring配置文件路径。如果没有配置Spring xml文件的路径,会默认加载classpath/META-INF下的spring/*.xml文件。 public void start() { String configPath = ConfigUtils.getProperty(SPRING_CONFIG); if (configPath == null || configPath.length() == 0) { configPath = DEFAULT_SPRING_CONFIG; } context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));

Dynamic Java Bytecode Manipulation Framework Comparison

孤街浪徒 提交于 2019-11-29 20:18:46
There are some frameworks out there for dynamic bytecode generation, manipulation and weaving (BCEL, CGLIB, javassist, ASM, MPS). I want to learn about them, but since I don't have much time to know all the details about all of them, I would like to see a sort of comparison chart saying the advantages and disadvantages of one versus the others and an explanation of why. Here in SO, I found a lot of questions asking something similar, and the answers normally said "you can use cglib or ASM", or "javassist is better than cglib", or "BCEL is old and is dying" or "ASM is the best because it gives

字节码和字节码增强

自作多情 提交于 2019-11-29 09:40:48
字节码 Java的一次编写到处运行就是靠的字节码技术,java通过javac命令编译源代码为字节码文件,流程如下: 通过字节码,可以进行各种AOP增强,比如ORM,热部署机制等。字节码有其规范,可以帮助其他JVM语言在JVM体系下运行,比如Scala,Groovy,Kotlin等。 字节码组成 魔数 所有.class文件的前四个字节都是魔数,魔数值是固定的 0xCAFEBABE (咖啡杯)。JVM根据关键字判断一个文件是否是一个.class文件,是的话才会继续进行操作。 版本号 版本号为魔数之后的四个字节,前两个表示次版本号,后两个表示主版本号。 常量池 在版本号之后的字节为常量池。常量池中存储两类常量:字面量和符号引用。 字面量表示代码中声明为final的常量值,符号引用如类和接口的全限名,字段名称和描述符,方法名称和描述符。 常量池分为两部分:常量池计数器和常量池数据区。 访问标志 常量池之后的两个字节描述Class是类还是接口,及是否被public,abstract,final等修饰。 当前类名 访问标志之后的两个字节,描述的是类的全限名,这两个字节保存的值为常量池中的索引值,根据索引值在常量池中找到这个类的全限名。 父类名称 当前类名后的两个字节,描述父类的全限名,同上,保存的是常量池中的索引值。 接口信息 父类名称之后的两个字节的接口计数器,描述了该类或父类实现的接口数量

Java字节码增强探秘

独自空忆成欢 提交于 2019-11-29 08:57:58
1.字节码 1.1 什么是字节码? Java之所以可以“一次编译,到处运行”,一是因为JVM针对各种操作系统、平台都进行了定制,二是因为无论在什么平台,都可以编译生成固定格式的字节码(.class文件)供JVM使用。因此,也可以看出字节码对于Java生态的重要性。之所以被称之为字节码,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取。在Java中一般是用javac命令编译源代码为字节码文件,一个.java文件从编译到运行的示例如图1所示。 对于开发人员,了解字节码可以更准确、直观地理解Java语言中更深层次的东西,比如通过字节码,可以很直观地看到Volatile关键字如何在字节码上生效。另外,字节码增强技术在Spring AOP、各种ORM框架、热部署中的应用屡见不鲜,深入理解其原理对于我们来说大有裨益。除此之外,由于JVM规范的存在,只要最终可以生成符合规范的字节码就可以在JVM上运行,因此这就给了各种运行在JVM上的语言(如Scala、Groovy、Kotlin)一种契机,可以扩展Java所没有的特性或者实现各种语法糖。理解字节码后再学习这些语言,可以“逆流而上”,从字节码视角看它的设计思路,学习起来也“易如反掌”。 本文重点着眼于字节码增强技术,从字节码开始逐层向上,由JVM字节码操作集合到Java中操作字节码的框架

Configure org.apache.log4j.ConsoleAppender with custom classloader

江枫思渺然 提交于 2019-11-29 06:42:59
I have a java class which creates a custom classloader based on javassist class loader on start up and then run the real program class. I'm getting the following error: log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable. log4j:ERROR The class "org.apache.log4j.Appender" was loaded by log4j:ERROR [javassist.Loader@6f97b10a] whereas object of type log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [java.net.URLClassLoader@5b414a8d]. log4j:ERROR Could not instantiate appender named "stdout". The problem is related to the

Replace content of some methods at runtime

﹥>﹥吖頭↗ 提交于 2019-11-29 05:29:58
I would like to replace the content of some methods at runtime. I know I can use javassist for this but it does not work because the classes I would like to enhance are already loaded by the system classLoader . How can I do, to replace the content of a method at runtime ? Should I try to unload the class ? How can I do that ? I saw it was possible but I could not figure out how to do it. If possible, I would like to avoid using an external lib for this, I would like to code it my-self. More information: - The class I would like to enhance is contained in a framework (in a jar file) - My code

Javassist: creating an interface that extends another interface with generics

断了今生、忘了曾经 提交于 2019-11-29 05:18:22
I am using javassist in a project and I need to create the following interface at runtime: package com.example; import org.springframework.data.repository.CrudRepository; import com.example.Cat; public interface CatRepository extends CrudRepository<Cat, Long> {} While I had no problem creating the interface CatRepository extending CrudRepository , I do not understand (from the docs and from looking at the source code), how to specify com.example.Cat and java.lang.Long as generics types to the super-interface. Please note that: com.example.Cat : created at runtime using javassist (no problems

SpringBoot(四)之优雅地日志处理

…衆ロ難τιáo~ 提交于 2019-11-29 01:26:56
一、简介 日志功能在j2ee项目中是一个相当常见的功能,在一个小项目中或许你可以在一个个方法中,使用日志表的Mapper生成一条条的日志记录,但这无非是最烂的做法之一,因为这种做法会让日志Mapper分布到了项目的多处代码中,后续很难管理。而对于大型的项目而言,这种做法根本不能采用。本篇文章将介绍,使用自定义注解,配合AOP,优雅的完成日志功能。 本文Demo使用的是Spring Boot框架,但并非只针对Spring Boot,如果你的项目用的是Spring MVC,做下简单的转换即可在你的项目中实现相同的功能。 二、日志管理的实现 在开始编码之前,先介绍下思路: 在Service层中,涉及到大量业务逻辑操作,我们往往就需要在一个业务操作完成后(不管成败或失败),生成一条日志,并插入到数据库中。那么我们可以在这些涉及到业务操作的方法上使用一个自定义注解进行标记,同时将日志记录到注解中。再配合Spring的AOP功能,在监听到该方法执行之后,获取到注解内的日志信息,把这条日志插入到数据即可。 好了,下面就对上面的理论付出实践。 1、自定义注解 这里我们自定义一个日志注解,该注解中的logStr属性将用来保存日志信息。自定义注解代码如下: @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD})