我正在使用Byte Buddy生成 JPA 实体和 JPA 存储库。我能够生成 JPA 实体,但无法继续生成相应的 JPA 存储库。以下是代表 Person 实体的代码,
import javax.persistence.*;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
protected Person(){}
@Override
public String toString() {
return String.format("Person[id=%d]",id,name);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用 Bute Buddy 生成上述内容,如下所示,
Class<?> type = new ByteBuddy()
.subclass(Object.class)
.name("Person")
.defineField("id", Integer.class, Visibility.PRIVATE)
.defineMethod("getId", Integer.class, Visibility.PUBLIC)
.intercept(FieldAccessor.ofBeanProperty())
.defineMethod("setId", void.class, Visibility.PUBLIC).withParameter(Integer.class)
.intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) …Run Code Online (Sandbox Code Playgroud) 我想实现这个 3rd-party 注释以将我的类的字段/属性映射到我的数据库表列。我可以在编译时轻松实现注释(如下面的示例代码所示),但我找不到在运行时执行此操作的方法。(我在运行时使用反射加载库。)
我的问题是如何在运行时加载库时实现相同的映射注释?Byte Buddy 可以为 Android 处理这个吗?
//3rd party annotation code
package weborb.service;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface MapToProperty {
String property();
}
Run Code Online (Sandbox Code Playgroud)
///////////////////////////////////////////////// ///
//Here is the implementation using non-reflection
import weborb.service;
Class Person
{
@MapToProperty(property="Person_Name")
String name;
@MapToProperty(property="Person_Age")
int age;
@MaptoProperty(property="Person_Name")
public String getName()
{
return this.name;
}
@MaptoProperty(property="Person_Name")
public void setName(String name)
{
this.name = name;
}
@MaptoProperty(property="Person_Age")
public int getAge()
{
return this.age;
}
@MaptoProperty(property="Person_Age")
public void …Run Code Online (Sandbox Code Playgroud) 我有以下课程:
package some.clazz.client;
import some.clazz.SomeClass;
public class SomeClassClient {
...
public SomeClass getProc();
...
}
Run Code Online (Sandbox Code Playgroud)
我已经通过在Maven 插件中使用ByteBuddy 转换getProc()从SomeClassClient类字节码中删除/缩小/删除了这个Java 方法。但是语句仍然存在并由!new MemberRemoval().stripMethods(ElementMatcher);net.bytebuddy:byte-buddy-maven-pluginimport some.clazz.SomeClass;CFR Java Decompiler
SomeClass类中没有任何其他对类的引用SomeClassClient。
如何从字节码中删除这个导入语句(我真的假设它位于常量池中)?因为我在尝试使用“SomeClassClient”类时仍然遇到 ClassNotFoundException。
我的课
public class MethodsRemover implements net.bytebuddy.build.Plugin {
...
@Override
public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassFileLocator classFileLocator) {
try{
return builder.visit(new MemberRemoval().stripMethods(
ElementMatchers.any().and(
isAnnotatedWith(Transient.class)
.and(
t -> {
log.info(
"ByteBuddy transforming class: {}, strip method: {}",
typeDescription.getName(),
t
);
return true;
}
) …Run Code Online (Sandbox Code Playgroud) 我使用 Byte Buddy 编写了一个代理,并尝试修改返回值。
代理代码(部分伪代码):
premain(String args, Instrumentation instrumentation) {
new AgentBuilder.Default().disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.type(ElementMatchers.is(target.class))
.transform(
(builder, typeDescription, classLoader, module) ->
builder
.visit(
Advice.to(CustomAdvice.class).on(ElementMatchers.named("methodName").and(ElementMatchers.isPublic()))))
.installOn(instrumentation);
}
public class CustomAdvice {
@Advice.OnMethodExit
public static String intercept(@Advice.Return String value) {
System.out.println("intercepted: " + value);
return "hi: " + value;
}
}
Run Code Online (Sandbox Code Playgroud)
我的建议有效,但我的建议的返回值没有被使用。
我想列出一个方法调用的所有方法。
void create() throws MyException {
System.out.println("TEST");
of("String").map(String::valueOf).get();
}
Run Code Online (Sandbox Code Playgroud)
在这个方法中我想列出
我习惯了下面的代码,如何找到一个方法中调用的所有方法?
public class MethodFinder {
public static void main(String[] args) throws Throwable {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("MyClass");
CtMethod method = ctClass.getDeclaredMethod("getItem1");
method.instrument(
new ExprEditor() {
public void edit(MethodCall m)
throws CannotCompileException
{
System.out.println(m.getClassName() + "." + m.getMethodName() + " " + m.getSignature());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
并获取除 String::valueOf 之外的所有方法
是否可以通过任何其他框架解决这个问题并不重要。
byte-buddy ×5
java ×5
bytecode ×2
android ×1
annotations ×1
bcel ×1
cglib ×1
javassist ×1
runtime ×1
spring-boot ×1