我是第一次尝试AOP,为此我开发了一个小而简单的例子,但我发现了一些问题。首先,Spring要求我通过打印以下错误向cglib库添加依赖项:
cannot proxy target class because cglib2 is not available
解决该问题并将依赖项添加到我的pom.xml文件后:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
我发现cglib创建了我的每个bean的代理,并且方法没有被执行。在这里你可以看到:
A类 : 包com.test.test.classes;
public abstract class A {
public abstract void doMoreStuff();
public void doStuff(){
System.err.println("Inside A.doStuff()");
}
}
B类 包com.test.test.classes;
public class B extends A{
@Override
public void doMoreStuff() {
System.err.println("Inside B.doMoreStuff()");
}
}
C类 包com.test.test.classes;
public class C extends A{
@Override
public void doMoreStuff() {
System.err.println("Inside C.doMoreStuff()");
}
}
方面 包com.test.test.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectAttempt {
@Around("execution(* com.test.test.classes.*.*(..))")
public void miAspecto(ProceedingJoinPoint joinPoint) throws Throwable{
System.err.println("Inside the Aspect");
System.err.println("Invoking " + joinPoint.getSignature());
}
}
春季背景
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="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 "
default-autowire="byName">
<aop:aspectj-autoproxy proxy-target-class="false"/>
<bean id="a1" class="com.test.test.classes.B" />
<bean id="a2" class="com.test.test.classes.C" />
<bean id="b" class="com.test.test.classes.B" />
<bean id="c" class="com.test.test.classes.C" />
<!-- Aspect -->
<bean id="logAspect" class="com.test.test.aspect.AspectAttempt" />
</beans>
测试 包com.test.test.testingAspects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.test.test.classes.A;
import com.test.test.classes.B;
import com.test.test.classes.C;
/**
* Unit test for simple App.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/context.xml" })
public class AppTest {
@Autowired
@Qualifier("a1")
private A a1;
@Autowired
@Qualifier("a2")
private A a2;
@Autowired
@Qualifier("b")
private B b;
@Autowired
@Qualifier("c")
private C c;
@Test
public void test() {
a1.doStuff();
a2.doStuff();
a1.doMoreStuff();
a2.doMoreStuff();
b.doStuff();
b.doMoreStuff();
c.doStuff();
c.doMoreStuff();
}
}
控制台日志
29-oct-2015 10:47:33 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
INFO: @TestExecutionListeners is not present for class [class com.test.test.testingAspects.AppTest]: using defaults.
29-oct-2015 10:47:33 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [context.xml]
29-oct-2015 10:47:33 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@149eb9f: startup date [Thu Oct 29 10:47:33 CET 2015]; root of context hierarchy
29-oct-2015 10:47:33 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@40afb9: defining beans [org.springframework.aop.config.internalAutoProxyCreator,a1,a2,b,c,logAspect,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy
Inside the Aspect
Invoking void com.test.test.classes.A.doStuff()
Inside the Aspect
Invoking void com.test.test.classes.A.doStuff()
Inside the Aspect
Invoking void com.test.test.classes.B.doMoreStuff()
Inside the Aspect
Invoking void com.test.test.classes.C.doMoreStuff()
Inside the Aspect
Invoking void com.test.test.classes.A.doStuff()
Inside the Aspect
Invoking void com.test.test.classes.B.doMoreStuff()
Inside the Aspect
Invoking void com.test.test.classes.A.doStuff()
Inside the Aspect
Invoking void com.test.test.classes.C.doMoreStuff()
29-oct-2015 10:47:36 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@149eb9f: startup date [Thu Oct 29 10:47:33 CET 2015]; root of context hierarchy
29-oct-2015 10:47:36 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@40afb9: defining beans [org.springframework.aop.config.internalAutoProxyCreator,a1,a2,b,c,logAspect,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy
知道问题可能是什么?
提前致谢
答案 0 :(得分:1)
到目前为止,我可以看到没有调用最终方法,因为AspectAttempt Aspect正在捕获所有方法,但执行不会继续。
因此,如果您想继续进行真正的通话,您需要在AspectAttempt.miAspecto中进行编辑,如下所示:
def reqProductVersions = TestRuns.createCriteria().list(max: reqNumberOfRecords, offset: startIndex) {
projections {
groupProperty "productVersion"
}
'in'("testType",filters.testTypes)
'in'("testSuiteName",suites)
eq("product",filters.product)
like("branch",filters.branch)
like("deploymentMode",filters.deploymentMode)
if(filters.tag){
isNotNull("tag")
ne("tag","")
}
if(!filters.jenkinsInstance.equals("%%")){
processedJenkinsRuns{
like("jenkinsServer",filters.jenkinsInstance)
}
}
cache true
order("date","desc")
}
// we need total count. createcriteria has issue when we ask total count with group property combined
def totalCount = TestRuns.createCriteria().get {
projections {
countDistinct "productVersion"
}
'in'("testType",filters.testTypes)
'in'("testSuiteName",suites)
eq("product",filters.product)
like("branch",filters.branch)
like("deploymentMode",filters.deploymentMode)
if(filters.tag){
isNotNull("tag")
ne("tag","")
}
if(!filters.jenkinsInstance.equals("%%")){
processedJenkinsRuns{
like("jenkinsServer",filters.jenkinsInstance)
}
}
cache true
}
def productVersionAndCount = [:];
productVersionAndCount.put("total",totalCount);
productVersionAndCount.put("productVersions",reqProductVersions);
return productVersionAndCount;
}
def getAllTemplateNames(def productVersions){
def templatesResults = ArtifactsInformation.findAllByP4ChangeListNumInList(productVersions);
Map<String, List<String>> templates = new HashMap<String, List<String>>();
templatesResults.each{ tmp ->
List<String> tempList = templates.get(tmp.p4ChangeListNum);
if(tempList == null){
tempList = new ArrayList<String>();
templates.put(tmp.p4ChangeListNum, tempList)
}
tempList.add(tmp.templateName);
}
return templates;
}
def getBuildStatusHomePageResults(int startIndex,int reqNumberOfRecords,BuildParamsDTO filters, def isCompareChecked){
**568 ->** def productVersionsAndCount = filters.junitAndSeleniumFilter?getProductVersionWithJunitAndSeleniumAndCriteria(filters,startIndex,reqNumberOfRecords):getProductVersionsWithCriteria(filters,startIndex,reqNumberOfRecords);
def productVersions = productVersionsAndCount.get("productVersions");
int totalRecords = productVersionsAndCount.get("total");
log.debug productVersions.toString()+" are selected as required product versions in getData"
Collections.sort(productVersions,Collections.reverseOrder());
Map<String, VersionDto> buildResults = new LinkedHashMap<String, VersionDto>();
productVersions.each{changeList ->
buildResults.put(changeList, new VersionDto(changeList))
}
if(productVersions.size() > 0){
getTestResults(productVersions, filters, buildResults);
}
def reqGroups = filters.testTypes;
def reqSuites =filters.testSuites ;
def dataToRender = [:]
dataToRender = buildDataTableObject(buildResults, reqGroups, reqSuites, filters, totalRecords, isCompareChecked);
return dataToRender;
}
看到唯一新的是jointPoint.proceed()调用。
希望它有所帮助。
答案 1 :(得分:0)
Around advice is declared using the @Around annotation. The first
parameter of the advice method must be of type ProceedingJoinPoint.
Within the body of the advice, calling proceed() on the
ProceedingJoinPoint causes the underlying method to execute