我将 Mongo DB 与 Spring Data 一起使用,一切正常,直到我决定使用 Spring AOP Aspects 进行日志记录。这是我的 spring 配置,Person Service 和 LoggingAspect 代码:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<context:spring-configured />
<context:component-scan base-package="com.vaap" />
<mongo:mongo host="127.0.0.1" port="27017" />
<mongo:db-factory dbname="rakeshdb" mongo-ref="mongo"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<bean id="personService" class="com.vaap.PersonService"></bean>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="loggingAspect" class="com.vaap.aop.LoggingAspect" />
</beans>
package com.vaap;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
public class PersonService implements IPersonService {
@Autowired
MongoTemplate mongoTemplate;
public static final String COLLECTION_NAME = "person";
public void addPerson(Person person) {
if (!mongoTemplate.collectionExists(Person.class)) {
mongoTemplate.createCollection(Person.class);
}
person.setId(UUID.randomUUID().toString());
// mongoTemplate.save(objectToSave, collectionName);
// DBObject dbObject = (DBObject) JSON.parse(jsonStr);
mongoTemplate.insert(person, COLLECTION_NAME);
}
public List<Person> listPerson() {
return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
}
public String getPersonJSON() {
BasicQuery basicQuery = new BasicQuery("{'status':'Active'}");
return mongoTemplate.find(basicQuery, String.class, COLLECTION_NAME)
.toString();
}
public void deletePerson(Person person) {
mongoTemplate.remove(person, COLLECTION_NAME);
}
public void updatePerson(Person person) {
mongoTemplate.insert(person, COLLECTION_NAME);
}
}
package com.vaap.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
@Component
@Configurable
@Aspect
public class LoggingAspect {
static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
@AfterThrowing(pointcut = "execution(* *.*(..))", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
log.error("An exception has been thrown in "
+ joinPoint.getSignature().getName() + "()");
log.error("Cause :" + e.getCause());
}
@Around("execution(* *.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("The method " + joinPoint.getSignature().getName()
+ "() begins with " + Arrays.toString(joinPoint.getArgs()));
try {
Object result = joinPoint.proceed();
log.info("The method " + joinPoint.getSignature().getName()
+ "() ends with " + result);
return result;
} catch (IllegalArgumentException e) {
log.error("Illegal argument "
+ Arrays.toString(joinPoint.getArgs()) + " in "
+ joinPoint.getSignature().getName() + "()");
throw e;
}
}
}
如果我评论<aop:aspectj-autoproxy proxy-target-class="true"/>
行一切正常,否则我会收到此错误:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mongoTemplate' defined in class path resource [SpringConfig.xml]:
Cannot resolve reference to bean 'mongoDbFactory' while setting constructor argument;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mongoDbFactory': Initialization of bean failed;
nested exception is org.springframework.aop.framework.AopConfigException:
Could not generate CGLIB subclass of class [class org.springframework.data.mongodb.core.SimpleMongoDbFactory]:
Common causes of this problem include using a final class or a non-visible class;
nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments
我知道,这可能不是 spring 问题,因为这是标准的 CGI Lib 行为,但是如果我想使用 XML 配置并想同时使用 spring 数据和 mongodb 和 spring aop 进行日志记录,我有什么选择。