使用在Tomcat上运行的Spring Data Neo4j 4 + AspectJ LTW进行延迟加载 [英] Lazy Loading using Spring Data Neo4j 4 + AspectJ LTW running on Tomcat
问题描述
我尝试了所有可能的方法,以使我的项目在Tomcat上运行,并切点模型(获取器),并使用AspectJ Load Time Weaver编织它们. 基本上,我遵循了Spring文档 Neo4j中的惰性/急切加载/获取相同的方法. /Spring-Data . 我的项目分为两个主要项目: -核心:spring-data-neo4j(存储库和配置),专用软件包中的域模型LoggingAspect和LazyLoadingAspect. p.s.我没有在XML文件中使用任何配置.我纯粹在使用注释. -内容:在Tomcat上运行的Web应用程序,它取决于核心项目,并且在域项目中调用getter方法时希望进行编织.
I went through all the possibilities trying to make my project running on Tomcat and point cut the model (getters) and woven them using AspectJ Load Time Weaver. Basically, I followed all the steps in the Spring Documentation http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable. I also followed the same approach mentioned Lazy/Eager loading/fetching in Neo4j/Spring-Data. My project is divided in two main project: - core: spring-data-neo4j (repository and configuration), domain-model in a dedicated package, LoggingAspect and LazyLoadingAspect. p.s. I am not using any configuration in XML files. I am using Annotation purely. - content: web application running on Tomcat which depends on core project and I want to weave when I invoke getter methods in the domain project.
运行核心本身,我设法使用maven插件使其运行并添加了Aspectj的依赖项.但是,当我移到Tomcat时,所有的一切都开始了.我尝试了所有可能性,例如使用-javaagent,创建自定义context.xml,将spring-instrument放入tomcat/lib文件夹等,等等.我收到以下异常:
Running the core itself I managed to get it running using maven plugin and adding the dependencies for aspectj. But all the hell starts when I move to Tomcat. I tried all the possibilities e.g using -javaagent, create the custom context.xml, put spring-instrument into tomcat/lib folder, etc etc. I am receiving the following exception:
java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [com.test.server.graph.domain.model.Sequence] with (proxy) object of type [org.springframework.beans.factory.aspectj.$Proxy96] - not supported for aspect-configured classes!
at org.springframework.beans.factory.wiring.BeanConfigurerSupport.checkExposedObject(BeanConfigurerSupport.java:173)
at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:143)
at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:63)
at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:88)
at com.test.server.graph.domain.model.Sequence.(Sequence.java:29)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.neo4j.ogm.annotations.EntityFactory.instantiate(EntityFactory.java:135)
at org.neo4j.ogm.annotations.EntityFactory.instantiateObjectFromTaxa(EntityFactory.java:110)
at org.neo4j.ogm.annotations.EntityFactory.newObject(EntityFactory.java:61)
at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:147)
at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:132)
at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:107)
at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:102)
at org.neo4j.ogm.context.RestModelMapper.mapEntity(RestModelMapper.java:157)
at org.neo4j.ogm.context.RestModelMapper.map(RestModelMapper.java:76)
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:94)
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:73)
at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:313)
at org.springframework.data.neo4j.template.Neo4jTemplate.query(Neo4jTemplate.java:217)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy58.query(Unknown Source)
pom.xml(core.project)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>${sdn.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>2.0.3-SNAPSHOT</version>
</dependency>
我的配置类(核心项目)
@org.springframework.context.annotation.Configuration
@ComponentScan(basePackages = "org.test.server.graph")
@EnableNeo4jRepositories(basePackages = "org.test.server.graph.repository")
@EnableAspectJAutoProxy
@EnableSpringConfigured
public class Neo4jConfig extends Neo4jConfiguration {
@Bean
public Configuration getConfiguration() {
Configuration config = new Configuration();
config.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver")
.setURI(System.getProperty("neo4j.host")).setCredentials(System.getProperty("neo4j.user"),System.getProperty("neo4j.password"));
return config;
}
@Bean
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(), "org.test.server.graph.domain" );
}
@Bean
@Scope(value = "prototype")
public Session getSession() throws Exception {
return super.getSession();
}
}
域模型类
按照Spring文档的建议,我注释了Domain模型中的类
As recommended by Spring Documentation I annotated the classes in the Domain model
@可配置
@Configurable
mvc-dispatcher-servlet(网络应用程序项目)
<context:spring-configured />
<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver" />
我尝试使用tomcat-maven-plugin和tomcat独立安装(v7和v8)运行.
I tried running using tomcat-maven-plugin and tomcat standalone installation (v7 and v8).
-更新-
Sequence.java
@NodeEntity
@Configurable
public class Sequence extends DatabaseObject {
@Relationship(type = "hasModifiedResidue", direction = Relationship.OUTGOING)
private List<AbstractModifiedResidue> hasModifiedResidue;
@Relationship(type = "referenceEntity", direction = Relationship.OUTGOING)
private ReferenceSequence referenceEntity;
public Sequence() {}
//getter and setters
}
DatabaseObject.java
@NodeEntity
@Configurable(
preConstruction = false
)
public abstract class DatabaseObject implements Serializable, Comparable<DatabaseObject> {
@GraphId
private Long id;
// other common attributes + getter and setters, no more annotation
LazyLoadingAspect
@Aspect
@Component
public class LazyFetchAspect {
@Autowired
private Neo4jOperations neo4jTemplate;
@Around("modelGetter()")
public Object autoFetch(ProceedingJoinPoint pjp) throws Throwable {
System.out.println(" Testing Aspect ");
return pjp.proceed();
}
@Pointcut("execution(public * com.test.server.graph.domain.model.*.get*(..))")
public void modelGetter() {
}
}
推荐答案
主要问题似乎在于您正在将方面应用于bean:
The main problem seems to be that you are applying aspects to beans:
Post-processor tried to replace bean instance of type [com.test.server.graph.domain.model.Sequence] with (proxy) object of type [org.springframework.beans.factory.aspectj.$Proxy96] - not supported for aspect-configured classes!
这行不通,因此您必须确保模型类是真实的POJO,而不是bean,并将它们从spring中排除. (确保在domain.model.*中没有spring注释)-也许如果您发布Sequence.java,我可以看到是什么引起了冲突.
This wont work, so you have to make sure your model classes are real POJOs and not beans and exclude them from spring. (Make sure that in domain.model.* there is no spring annotation) - maybe if you post your Sequence.java I can see what might be causing the conflict.
另一方面,您必须确保Aspectj仅分配给模型,而不分配给任何bean.因此,请确保您有一个/META-INF/aop.xml仅包含pojo模型:
On the other hand you have to make sure that aspectj is only assigned to the models and not any beans. So make sure you have a /META-INF/aop.xml that only includes your pojo models:
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.test.server.graph.domain.model.*" />
</weaver>
<aspects>
<!-- weave in just this aspect -->
<aspect name="my.util.aspects.Neo4jFetchAspect" />
</aspects>
</aspectj>
我的pom.xml的一部分(我现在有一个不同的设置-这就是为什么弹簧版本这么旧的原因):
Parts of my pom.xml (i have a different setup by now - thats why the spring version is so old):
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
我没有任何特殊的构建插件或类似的
I dont have any special build plugins or similar
这篇关于使用在Tomcat上运行的Spring Data Neo4j 4 + AspectJ LTW进行延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!