【问题标题】:Use Spring AOP on class with final members and no default constructor在具有最终成员且没有默认构造函数的类上使用 Spring AOP
【发布时间】:2022-02-09 10:00:20
【问题描述】:

我正在尝试使用spring aop。 我已经配置了以下方面:

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

    @Around(value = "@annotation(benchmark)")
    public void do(final ProceedingJoinPoint joinPoint, final Benchmark benchmark)            throws Throwable {

    logger.error("Before");
    joinPoint.proceed();
    logger.error("After");
}

这是一个使用我的服装注释的类的示例

@Component
public class AttributeContainer {
    private static final Logger logger = LoggerFactory.getLogger(AttributeContainer.class);
    private final int y;

    public AttributeContainer(int y){
          this.y = y;
    }

    @Benchmark
    public void getAttribute() {
         logger.error("Inside Attribute call...");
    }
}

当我加载我的应用程序时,出现以下异常:

nested exception is org.springframework.aop.framework.AopConfigException: Could not  generate CGLIB subclass of class [class   com.test.AttributeContainer]: 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   were given:
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:201)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)

更新 添加我的 spring 配置 xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

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

  <context:component-scan base-package="com.test.*" />

  <bean id="test" class="com.test.AttributeContainer">
    <constructor-arg value="34"/>
  </bean>
</beans>

为什么 CGlib 无法创建子类? 谢谢!

【问题讨论】:

  • 我熟悉AspectJ,但不熟悉Spring AOP。无论如何,如果您提供一个完整的、可编译的、最小的代码示例来重现您的问题,也许我可以看到或提出一些建议。你的问题有点太不具体了。
  • 谢谢!我在我的问题中添加了更多细节。 @kriegaex
  • 如果您提供无参数 ctor 是否有效?
  • 我不能……因为 y 是最终的。 @戴夫牛顿

标签: spring aop aspectj spring-aop cglib


【解决方案1】:

请在adviceMethod.Hope的目标方法类中定义一个无参数公共或默认类型构造函数,它将解决您的问题。

【讨论】:

    【解决方案2】:

    Could not instantiate bean class [...]: No default constructor found

    这看起来更像是一个 Spring bean 配置/实例化问题,而不是与 Spring AOP 或 AspectJ 相关的任何问题。

    在你解决这个问题之后,你可能会遇到其他问题:

    • 在您的建议@Around(value = "@annotation(benchmark)") 中,您应该注意拼写。我猜您希望您的注释 Benchmark 以大写“B”开头,而不是小写。
    • 您的第二个建议参数final Benchmark benchmark 来自哪里?它不受argsthistarget 的约束。无论如何,您都不会在建议中使用它,因此您可以将其删除。

    更新以回答您的其他问题:

    AopConfigException: Could not generate CGLIB subclass of class
    [class com.test.AttributeContainer]: 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 were given
    

    此异常消息似乎很不言自明。你读过吗?您在没有参数的情况下实例化您的组件,但只提供一个绝对需要参数的构造函数。这就是Spring抱怨的原因。也许您想阅读 Spring 教程?

    【讨论】:

    • 您对 init 问题的看法是正确的。我解决了问题并得到了上述异常(我更新了主要问题)。顺便说一句,@annotation(benchmark) 有效,但无论如何我都会改变它..!谢谢! @kriegaex,对更新的异常有任何想法吗?
    • 那你怎么解释这样一个事实,当我从 AttributeContainer 中删除注释时,我没有任何异常,所以 Spring wise 我很好。我的问题是,由于某种原因,CGLIB 不能继承 AttributeContainer。我添加了我的 spring 配置 xml 来向您展示 AttributeContainer 已正确初始化。 @kriegaex
    • CGLIB 创建一个动态代理。这就是 Spring 实现 AOP 的方式。 CGLIB 要求类被代理以提供默认构造函数。所以请提供一份。或者切换到成熟的 AspectJ 而不是 Spring AOP。它也适用于 Spring。
    • 由于我的最终成员,我无法提供默认构造函数。但是我可以尝试使用 AspectJ,我读过它,你能给我一个方向吗?你会做什么不同的事情? @kriegaex 谢谢你们的cmets!
    • AspectJ 语法是 Spring AOP 语法的超集。您可以执行与 Spring AOP 相同的操作以及更多操作,并且不需要任何 Java 或 CGLIB 动态代理。在eclipse.org/aspectj,您可以找到该工具和文档。
    猜你喜欢
    • 2012-09-01
    • 2014-04-15
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多