3

私はspringaopとspringconfigファイルの下で手を試しています:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" 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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="eddie" class="com.springinaction.Instrumentalist">
        <property name="instrument" ref="violin"></property>
        <property name="song" value="Samarame"></property>

    </bean>


    <bean id="kenny" class="com.springinaction.Instrumentalist">
        <property name="song" value="SAMARAME "></property>
        <property name="instrument" ref="saxopone"></property>
    </bean>

    <bean id="hank" class="com.springinaction.OneManBand">
        <property name="instruments">
            <props>
                <prop key="GUITAR">STRUM STRUM STRUM</prop>
                <prop key="CYMBAL">CRASH CRASH CRASH CRASH</prop>
                <prop key="HARMONICA">HUM HUM HUM</prop>
            </props>
        </property>
    </bean>

    <bean id="guitar" class="com.springinaction.Guitar">
    </bean>

    <bean id="violin" class="com.springinaction.Violin">
    </bean>

    <bean id="tabala" class="com.springinaction.Tabala">
    </bean>

    <bean id="saxopone" class="com.springinaction.Saxophone">
    </bean>

    <bean id="audience" class="com.springinaction.Audience"></bean>

    <aop:config>

        <aop:aspect ref="audience">

            <aop:before pointcut="execution(* com.springinaction.Performer.perform(..))" method="takeSeats()"/>
        </aop:aspect>
    </aop:config>

</beans>

コードを実行すると、次のようなエラーが発生します。

スレッド「main」の例外org.springframework.beans.factory.BeanNotOfRequiredTypeException:「eddie」という名前のBeanはタイプ[com.springinaction.Instrumentalist]である必要がありますが、実際にはorg.springframework.beans.factoryでタイプ[$Proxy4]でした。 .support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java :1008)com.springinaction.Main.main(Main.java:12)で

<aop:config>春の設定ファイルの要素にコメントすると、完全に実行されています。

なぜそれが起こっているのですか?

4

1 に答える 1

7

デフォルトでは、Springはプロキシクラスを使用してAOPを適用します。プロキシクラスは動的に作成され、多数のインターフェイスを実装します。'handler'オブジェクトを渡します。このオブジェクトは、これらのインターフェイスメソッドのいずれかが呼び出されたときに呼び出されます。プロキシオブジェクトのJavadocはここで読むことができます。

アプリケーションコンテキスト内のすべてのBeanが初期化された後、Springは必要な後処理を実行します。これには、AOPアドバイスの適用が含まれます。Springは、Beanを名前のプロキシオブジェクトに置き換えeddieます。プロキシオブジェクトは、上記の例では、元のオブジェクトに呼び出しを渡す前に、別のオブジェクトのメソッドを呼び出します。名前の付いたBeanを要求するたびeddieに、実際のオブジェクトではなくプロキシオブジェクトを取得します。

Main上記のスタックトレースの下部に記載されているクラスのソースは見つかりませんでしたが、残りのコードのほとんどはここで見つかりました。とにかく、Mainクラスでは、あなたは次のようなことをしているようです

Instrumentalist eddie = (Instrumentalist) appContext.getBean("eddie", Instrumentalist.class);

getBean(String, Class)Springアプリケーションコンテキストのメソッドは、返されたBeanが指定されたクラスのものであることを確認し、そうでない場合は例外をスローします。これは、上記の例で起こったことです。プロキシオブジェクトはのインスタンスではなく、 。Instrumentalistと呼ばれる独自のプロキシクラスのインスタンスです$Proxy4Instrumentalist(すべてのプロキシクラスが拡張されるため、このプロキシクラスをのサブクラスにすることはできませんjava.lang.reflect.Proxy)。

プロキシクラスは、作成時に使用されたすべてのインターフェイスを常に実装します。InstrumentalistSpringはがを実装していることに気付くPerformerので、Springが作成するプロキシクラスもを実装しPerformerます。上記の行を次のように置き換えることができます

Performer eddie = (Performer) appContext.getBean("eddie", Performer.class);

perform()また、でメソッドを呼び出すだけでよい場合はeddie、コードが機能するはずです。

于 2010-08-28T14:15:30.740 に答える