Java 方面停用Spring控制器映射

Java 方面停用Spring控制器映射,java,spring,aop,spring-aop,Java,Spring,Aop,Spring Aop,我创建了一个Spring网站。 我使用了一个抽象的通用控制器类,具有不同的实现。 如果我不在任何控制器上激活Aspect类,它工作得很好 如果激活某个方面,则所有映射似乎都被停用: 调试:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping-未找到[/contact/2]的处理程序方法 警告:org.springframework.web.servlet.PageNotFound-在名

我创建了一个Spring网站。 我使用了一个抽象的通用控制器类,具有不同的实现。 如果我不在任何控制器上激活Aspect类,它工作得很好

如果激活某个方面,则所有映射似乎都被停用:

调试:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping-未找到[/contact/2]的处理程序方法
警告:org.springframework.web.servlet.PageNotFound-在名为“appServlet”的DispatcherServlet中找不到URI为[/clubhelperbackend/contact/2]的HTTP请求的映射

这是我的抽象控制器:

public abstract class AbstractController<T extends Data> implements ClubController<T> {

protected Dao<T> dao;
private Class<T> elementClass;

public AbstractController(Dao<T> dao, Class<T> element) {
    super();
    this.dao = dao;
    this.elementClass = element;
}

@Override
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getAsView(@PathVariable("id") long id, @RequestParam(required = false) boolean ajax, Model m) {
    String mapping = elementClass.getSimpleName();
    m.addAttribute(mapping, getById(id));
    return mapping + "Get" + (ajax ? "Ajax" : "");
}

@Override
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "application/json")
public T delete(@PathVariable("id") long id) {
    T obj = getById(id);
    // dao.delete(id);
    return obj;
}
}
这是my beans.xml的一部分:

<aop:aspectj-autoproxy>
    <aop:include name="mysqlDbCheckAspect" />
    <aop:include name="daoLoggerAspect" />
    <aop:include name="controllerSecurityAspect" />
    <aop:include name="deletedStorageAspect" />
</aop:aspectj-autoproxy>

我可以通过评论DeletedStorageSpect来恢复全部功能

是什么导致了这种行为?为什么映射上的方面不能被识别?控制器上是否不允许使用方面


希望得到一些帮助。

我不是AOP专家。但通过查看您的代码,我可以说抽象类没有执行,这可能是根本原因。所以必须修改切入点执行表达式

解决方案1 若您并没有对子类使用delete签名,那个么您可以轻松地移动到类似于bello的抽象表达式。上面说的只是包裹里的东西

@Pointcut("execution (public * de.kreth.clubhelperbackend.controller.*.*.delete(..))")
private void invocation() {
}
解决方案2 对于这样的表达式,可以使用逻辑门

@Pointcut("target(de.kreth.clubhelperbackend.controller.abstr.AbstractController)")
private void anyAbstractOperation() {}

@Pointcut("execution(public * *.delete(..))")
private void anyDeleteOperation() {}


@Pointcut("anyAbstractOperation() && anyDeleteOperation()")
private void invocation() {}
参考资料:
1.

二,

三,

解释 关于这个和目标

这限制了与连接点的匹配,其中bean引用是给定类型的实例,而目标限制了与连接点的匹配,其中目标对象是给定类型的实例。前者在SpringAOP创建基于CGLIB的代理时起作用,后者在创建基于JDK的代理时使用。假设目标类实现了一个接口:

public class FooDao implements BarDao {
    ...
}
@Pointcut("target(org.baeldung.dao.BarDao)")
在这种情况下,Spring AOP将使用基于JDK的代理,您应该使用目标PCD,因为代理对象将是proxy类的实例,并实现BarDao接口:

public class FooDao implements BarDao {
    ...
}
@Pointcut("target(org.baeldung.dao.BarDao)")
另一方面,如果FooDao未实现任何接口或proxyTargetClass属性设置为true,则代理对象将是FooDao的子类,并且可以使用此PCD:

@Pointcut("this(org.baeldung.dao.FooDao)")

默认情况下,将AOP与Spring一起使用时,Spring会创建代理。根据您是否在类上实现接口这一事实,它将创建一个JDK动态代理(基于接口)或基于CGLIB的代理(基于类)


看见简而言之,将代理目标class=true添加到
@M.Deinum:就是这样!非常感谢。我不太明白它的作用。如果你在回答中解释,我会接受。如果我删除组件注释,则不会触发任何方面(甚至不会实例化?)。我尝试了在其他类上工作的方面。我是否正确理解,删除接口也应该工作?理论上,这应该像创建基于类的代理一样工作。
public abstract class AbstractController<T extends Data> implements ClubController<T> {
<aop:aspectj-autoproxy proxy-target-class="true">