如何解决BeanNotOfRequiredTypeException

时间:2015-08-17 08:48:10

标签: spring

我正在编写一个小应用程序来检查" AfterAdvice"的功能。 spring-AOP中的概念,但我得到一个与xml文件相关的异常(我想)请帮我解决异常

的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-4.0.xsd">
<bean id="pinCheck" class="com.nt.advice.AtmPinVerifierAdvice" />
<bean id="targetBean" class="com.nt.service.AtmPinGenerator" />
<bean id="pfb" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="targetBean" />
    <property name="interceptorNames">
        <list>
            <value>pinCheck</value>
        </list>
    </property>
  </bean>
</beans>

ClientApp.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import com.nt.service.AtmPinGenerator;
public class ClientApp {
public static void main(String[] args) {
    //activate IOC container
    ApplicationContext ctx = new    FileSystemXmlApplicationContext("src/com/nt/cfgs/applicationContext.xml");
    //get proxy obj
    AtmPinGenerator gen = ctx.getBean("pfb",AtmPinGenerator.class);
    //call b.method
    gen.pinGenerator();
  }

}

AtmPinGenerator.java

import java.util.Random;
public class AtmPinGenerator extends Random {
//generating pin
public int pinGenerator(){
    //creat java.util.Random object 
    Random rad = new Random();
    //use nextInt() to generate random pin of 4 digits
    int pin = rad.nextInt(9999);
return pin;
  }//pinGenerator
}

AtmPinVerifierAdvice.java

import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AtmPinVerifierAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object retValue, Method method, Object[] args,
        Object target) throws Throwable {
    System.out.println(retValue);
    Integer pin = (Integer)retValue;
    //if generated pin is less than four digit throw an exception
    if(pin<=999)
        throw new IllegalArgumentException("invalid pin");
  }//afterReturning
}//AtmPinVerifierAdvice

如果我运行上述应用程序,我将收到此异常

输出

Aug 17, 2015 2:03:57 PM     org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing     org.springframework.context.support.FileSystemXmlApplicationContext@3ff14318:     startup date [Mon Aug 17 14:03:57 IST 2015]; root of context hierarchy
Aug 17, 2015 2:03:57 PM     org.springframework.beans.factory.xml.XmlBeanDefinitionReader     loadBeanDefinitions
INFO: Loading XML bean definitions from file     [G:\java\Frameworks\SpringAOP\AOPProj6(After advice - pin verifier     decl)\src\com\nt\cfgs\applicationContext.xml]
Exception in thread "main"     org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named     'pfb' must be of type [com.nt.service.AtmPinGenerator], but was actually of type     [com.sun.proxy.$Proxy2]
    at     org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Abstract    BeanFactory.java:375)
at     org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBe    anFactory.java:199)
at     org.springframework.context.support.AbstractApplicationContext.getBean(AbstractA    pplicationContext.java:962)
at test.ClientApp.main(ClientApp.java:14)

我不知道为什么会遇到异常。请任何人帮助我为什么会出现这种异常?

1 个答案:

答案 0 :(得分:2)

默认情况下,Spring使用JDK动态代理(基于接口)来应用AOP。

AtmPinGenerator扩展Random实施Serializable。 Spring看到了界面并使用基于接口的代理。您将获得仅实现Serializable接口的代理。

你有3个选择来解决它

  1. 通过配置ProxyFactoryBean
  2. 强制使用基于类的代理
  3. 创建界面并实施
  4. 通过不扩展Random强制基于类的代理。
  5. 最后一个选项是最容易的,只是不扩展Random,这将强制使用基于类的代理。

    public class AtmPinGenerator {
    
        public int pinGenerator(){
            Random rad = new Random();          
            return rad.nextInt(9999);
        }
    }
    

    您还可以将proxyTargetClass的{​​{1}}属性设置为ProxyFactoryBean,然后您无需更改班级。

    true

    最后一个选项是引入一个接口,只需在其上公开<property name="proxyTargetClass" value="true" /> 方法,让pinGenerator()实现该接口。

    AtmPinGenerator

    这样您就可以使用基于接口的代理。在public interface PinGenerator { int pinGenerator(); } public class AtmPinGenerator implements PinGenerator { ... } 方法中,现在使用main界面而不是PinGenerator