我经历了尝试让我的项目在Tomcat上运行并切入模型(getter)并使用AspectJ Load Time Weaver编织它们的所有可能性。 基本上,我遵循了Spring文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable中的所有步骤。我也遵循了Lazy/Eager loading/fetching in Neo4j/Spring-Data提到的相同方法。 我的项目分为两个主要项目: - 核心:spring-data-neo4j(存储库和配置),专用包中的域模型,LoggingAspect和LazyLoadingAspect。附:我没有在XML文件中使用任何配置。我纯粹使用Annotation。 - 内容:在Tomcat上运行的Web应用程序依赖于核心项目,我想在域项目中调用getter方法时进行编织。
运行核心本身我设法使用maven插件运行并添加了aspectj的依赖项。但是当我搬到Tomcat时,一切都开始了。我尝试了所有的可能性,例如使用-javaagent,创建自定义context.xml,将spring-instrument放入tomcat / lib文件夹等等。我收到以下异常:
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 Documentation的建议,我在Domain模型中注释了类
@Configurable
mvc-dispatcher-servlet(webapp项目)
<context:spring-configured />
<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver" />
我尝试使用tomcat-maven-plugin和tomcat独立安装(v7和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() {
}
}
答案 0 :(得分:0)
主要问题似乎是你将方面应用于bean:
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,我可以看到可能导致冲突的原因。
另一方面,你必须确保aspectj仅分配给模型而不是任何bean。因此,请确保您的/META-INF/aop.xml仅包含您的pojo模型:
<!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的一部分(我现在有不同的设置 - 这就是为什么春天版本太旧了):
<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>
我没有任何特殊的构建插件或类似的
答案 1 :(得分:0)
在应用了所有建议的建议之后,这是我的输出。
2016-06-15 09:15:21,144 INFO [localhost-startStop-1] DispatcherServlet: FrameworkServlet 'mvc-dispatcher': initialization started
2016-06-15 09:15:21,166 INFO [localhost-startStop-1] XmlWebApplicationContext: Refreshing WebApplicationContext for namespace 'mvc-dispatcher-servlet': startup date [Wed Jun 15 09:15:21 BST 2016]; root of context hierarchy
2016-06-15 09:15:21,198 INFO [localhost-startStop-1] XmlBeanDefinitionReader: Loading XML bean definitions from ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]
2016-06-15 09:15:21,683 INFO [localhost-startStop-1] DefaultListableBeanFactory: Overriding bean definition for bean 'org.springframework.context.config.internalBeanConfigurerAspect' with a different definition: replacing [Root bean: class [org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=aspectOf; initMethodName=null; destroyMethodName=null] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration; factoryMethodName=beanConfigurerAspect; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/context/annotation/aspectj/SpringConfiguredConfiguration.class]]
2016-06-15 09:15:21,866 INFO [localhost-startStop-1] PropertySourcesPlaceholderConfigurer: Loading properties file from class path resource [core.properties]
2016-06-15 09:15:21,876 INFO [localhost-startStop-1] DefaultContextLoadTimeWeaver: Could not obtain server-specific LoadTimeWeaver: Could not initialize TomcatLoadTimeWeaver because Tomcat API classes are not available
2016-06-15 09:15:21,877 INFO [localhost-startStop-1] DefaultContextLoadTimeWeaver: Found Spring's JVM agent for instrumentation
[WebappClassLoader@5b34e5c9] info AspectJ Weaver Version 1.8.9 built on Monday Mar 14, 2016 at 21:18:16 GMT
[WebappClassLoader@5b34e5c9] info register classloader org.apache.catalina.loader.WebappClassLoader@5b34e5c9
**[WebappClassLoader@5b34e5c9] info using configuration /Users/SearchV2/content/target/classes/META-INF/aop.xml**
**[WebappClassLoader@5b34e5c9] info using configuration file:/Users/.m2/repository/org/springframework/spring-aspects/4.3.0.RELEASE/spring-aspects-4.3.0.RELEASE.jar!/META-INF/aop.xml**
** REGISTERING MY ASPECT **
[WebappClassLoader@5b34e5c9] info register aspect com.test.server.graph.aop.LazyFetchAspect
PostProcessorRegistrationDelegate$BeanPostProcessorChecker: Bean 'neo4jConfig' of type [class com.test.server.graph.config.Neo4jConfig$$EnhancerBySpringCGLIB$$f406a5c8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-06-15 09:15:22,267 INFO [localhost-startStop-1] Neo4jConfiguration: Initialising PersistenceExceptionTranslationPostProcessor
[WebappClassLoader@5b34e5c9] weaveinfo Join point 'method-execution(java.lang.String com.test.server.graph.domain.model.DatabaseObject.getStId())' in Type 'com.test.server.graph.domain.model.DatabaseObject' (DatabaseObject.java:82) advised by around advice from 'com.test.server.graph.aop.LazyFetchAspect' (LazyFetchAspect.java)
....更多的吸气者被告知。
在做一些查询后,我得到以下异常:
SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.NoSuchMethodError: com.test.server.graph.aop.LazyFetchAspect.aspectOf()Lcom/test/server/graph/aop/LazyFetchAspect;] with root cause
java.lang.NoSuchMethodError: com.test.server.graph.aop.LazyFetchAspect.aspectOf()Lcom/test/server/graph/aop/LazyFetchAspect;
at com.test.server.graph.domain.model.DatabaseObject.getStId(DatabaseObject.java:82)