由于“切入点中的正式未绑定”,Spring AOP BeanCreationException

Posted

技术标签:

【中文标题】由于“切入点中的正式未绑定”,Spring AOP BeanCreationException【英文标题】:Spring AOP BeanCreationException due to "formal unbound in pointcut" 【发布时间】:2019-02-19 17:08:58 【问题描述】:

我对 Spring AOP 有疑问。

我正在尝试在 Spring MVC 应用程序中实现方面。

我得到的错误是:

Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.cache.annotation.AnnotationCacheOperationSource#0':
Initialization of bean failed; nested exception is
  java.lang.IllegalArgumentException:
  error at ::0 formal unbound in pointcut 

是什么导致了这个问题?

在 XML 文件中我有这个:

<aop:aspectj-autoproxy proxy-target-class="true"/>

我的方面类:

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ApplicationMonitor 
    private static final Logger logger = Logger.getLogger(ApplicationMonitor.class);

    @Pointcut(value = "execution(* hr.mycompany.controller.impl.MyCompanyController.update(Object))") 
    public void updateMC(Object obj)

    @Before(value="ApplicationMonitor.updateMC(Object)")
    public void beforeUpdateMC(JoinPoint jp) 
        Object obj = jp.getArgs()[0];
        logger.info("beforeUpdateMC " + obj);
    

在 pom.xml 文件中我有这个依赖项:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.8.10</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.10</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.10</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>

编辑(更改切入点后):

我更改了切入点,现在我收到如下错误:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [hr.mycompany.dao.IGenericHibernateDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)


09:11:27,871 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/BasicData-portlet]] (http--0.0.0.0-8083-2) StandardWrapper.Throwable: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyCompanyService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private hr.mycompany.dao.IGenericHibernateDao hr.mycompany.services.impl.MyCompanyService.vwObjectDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [hr.mycompany.dao.IGenericHibernateDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)

我的应用有多个层和类,如下所示:

@Controller 
public class MyCompanyController implements IMyCompanyController

    @Autowired
    private IMyComapnyService myCompanyService;




@Service
public class MyCompanyService implements IMyComapnyService 

    @Autowired
    private IGenericHibernateDao<Object, Integer>  vwObjectDao;


我正在尝试为@Controller 和@Service @Autowired 方法提供建议。

【问题讨论】:

您必须在@Pointcut(value = "execution(* hr.mycompany.controller.impl.MyCompanyController.update(Object))") 中添加and args(obj),例如@Pointcut(value = "execution(* hr.mycompany.controller.impl.MyCompanyController.update(Object)) and args(obj)") 不是and,是&amp;&amp;。可能这里回答的大家应该先学习一下 Spring AOP 或者 AspectJ 语法。 ;-) @kriegaex:我实际上在 manning 的 book spring in action 第 4 版中读到了,根据本书,它支持两者,但刚刚经过测试,看来你是对的。 AND 是 AFAIK,仅用于 XML 配置,其中与号和管道相当讨厌。 是的,你是对的,它是在 XML 中使用的 【参考方案1】:

用户 heonlyrao 提出了正确的建议,但切入点语法错误。你想这样做:

    @Pointcut("execution(* hr.mycompany.controller.impl.MyCompanyController.update(*)) && args(obj)") 
    public void updateMC(Object obj) 

    @Before("updateMC(obj)")
    public void beforeUpdateMC(JoinPoint jp, Object obj) 
        // Not needed if parameter is bound via args()
        // Object obj = jp.getArgs()[0];
        logger.info("beforeUpdateMC " + obj);
    

或者,类似于 heonlyrao 的建议,如果您不在多个建议中重复使用相同的切入点,您也可以内联它:

    @Before("execution(* hr.mycompany.controller.impl.MyCompanyController.update(*)) && args(obj)")
    public void beforeUpdateMC(JoinPoint jp, Object obj) 
        // Not needed if parameter is bound via args()
        // Object obj = jp.getArgs()[0];
        logger.info("beforeUpdateMC " + obj);
    

解释:您的错误消息显示:formal unbound in pointcut。这意味着您要么在切入点中使用形式参数和/或在切入点中未反映的建议方法签名,反之亦然。

【讨论】:

我改变了切入点,现在我得到了这样的错误: 原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到类型 [hr.mycompany.dao.IGenericHibernateDao] 的合格 bean依赖项:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注释:@org.springframework.beans.factory.annotation.Autowired(required=true) org.springframework.beans.factory.BeanCreationException:创建名为“MyCompanyService”的bean时出错:注入自动装配依赖失败; 我有多层应用程序,我正在尝试建议 @Controller 和 @Service 类方法 这是后续配置问题,与原问题无关。 你能告诉我问题出在哪里吗? 我不能,因为这似乎是一个配置(例如 bean 命名)问题,我看不到您的配置,因为没有 MCVE。由于问题不再与 AOP 相关,而且我是 AOP 专家,而不是 Spring 用户,而且新问题是关于依赖注入的,我认为您应该通过接受我的回答来结束这个问题,为您的新问题创建一个 MCVE然后向 MCVE 提出一个新问题,也许还可以提供一个指向该问题的链接,以便人们了解您的来源。谢谢,克里斯。 :-)

以上是关于由于“切入点中的正式未绑定”,Spring AOP BeanCreationException的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot AOP学习:Spring AOP实现日志功能

基于Spring-AOP的自定义分片工具

Spring AOP之AopProxy代理对象

Spring AOP中的几个概念

spring中的ioc和aop概念

spring源码剖析AOP实现原理剖析