我想轉換類,使Spring可以看到轉換後的註釋。這將允許我動態注入@Entity註釋,以便Spring Boot將其註冊爲數據使用的託管類型。ByteBuddy @Entity註解對Spring引導不可見ClassPathBeanDefinitionScanner basePackages掃描
註釋轉換工作正常,但Spring Boot似乎在缺少轉換版本的文件jar級別執行包掃描。這意味着Spring沒有看到註釋,因爲它正在分析JAR本身內的類文件的輸入流。
初始彈簧候選組件掃描如下:
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
的getResources調用最終在PathMatchingResourcePatternResolver結束 - 在這種情況下doFindAllClassPathResources
是彈簧加載器ByteBuddy的範圍之外?
ClassLoader cl = getClassLoader();
Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
加載資源後,春加載類的元數據(一個缺少註釋)
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
以上getMetadataReader方法調用最終在
final class SimpleMetadataReader implements MetadataReader
結束了它使用ASM ClassReader訪問類和註釋元數據。這顯然沒有找到Bytebuddy發佈的@Entity註釋。
我不確定是否應該以某種方式將Classloader鏈接到ByteBuddy或重寫Springs SimpleMetadataReader以使我自己的實現由ByteBuddy支持。
有什麼建議嗎?我正在使用AgentBuilder轉換註釋,並在彈簧引導啓動之前運行它。
public static void main(String[] args) {
EntityAgent.install(ByteBuddyAgent.install());
InversionContainer.startInversion(args);
}
我ByteBuddy默認地將Impl的完整性:
**
* Transform all Non-Abstract Classes which extend BaseEntity
* to have the annotation Entity
*/
public class EntityAgent {
/**
* Installs the agent builder to the instrumentation API.
*/
public static void install(Instrumentation inst) {
createAgentBuilder().installOn(inst);
}
/**
* Creates the AgentBuilder that will redefine any class extending BaseEntity
*/
private static AgentBuilder createAgentBuilder() {
return new AgentBuilder.Default()
.with(toSystemError())
.with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
.with(AgentBuilder.InitializationStrategy.SelfInjection.EAGER)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.type(getClassMatcher())
.transform(getTransformer());
}
/**
* Set Entity annotation on Class
*/
private static AgentBuilder.Transformer getTransformer() {
return (builder, typeDescription, classloader) -> builder.annotateType(AnnotationDescription.Builder.ofType(Entity.class).build());
}
/**
* Find any non-abstract class that extends BaseEntity
*/
private static ElementMatcher.Junction<TypeDescription> get ClassMatcher() {
return ElementMatchers.isSubTypeOf(BaseEntity.class).and(ElementMatchers.not(ElementMatchers.isAbstract()));
}
}
我回顧Unable to instrument apache httpclient using javaagent for spring boot uber jar application
讓我知道如果你想要更多的實施細節。我想幹淨地整合bytebuddy和spring,這樣我就可以用spring組件註釋來設置類。
這就是我想的。我可能會實現我自己的Spring ResourceLoader來做到這一點,或者實現我自己的MetadataReader來重新掃描類路徑上的資源,以獲取正確的引用。 與我上面的Bytebuddy代理有一個簡單的方法來確定它的掃描範圍嗎?它正在掃描所有內容,我想將它的掃描範圍限制在僅檢查basePackage中的類「com.system。*」,這可能會使其更快。當我想要完全忽略這些軟件包時,我看到成千上萬的IGNORES。 – John
您可以爲這些包空間設置忽略匹配器。 Java工具API沒有辦法壓縮包,但Byte Buddy真的很便宜。一切都懶散地解決了。 –