Java aop ComponentScanが機能せず、AnnotationConfigApplicationContextgetBeanが機能しない

3
parthi 2020-01-16 05:28.

(xml configの代わりに)AOPのアノテーションの使用について友人に示すための簡単なクラスのセットを作成しました。@ComponentScanを機能させることができず、AnnotationConfigApplicationContextgetBeanも誤動作します。私は2つのことを理解したかった。以下のコードを参照してください:

PersonOperationsI.java

package samples.chapter3;

import org.springframework.stereotype.Component;

@Component
public interface PersonOperationsI {

    public String getName();

}

PersonOperations.java

/**
 * 
 */
package samples.chapter3;

import org.springframework.stereotype.Component;

@Component
public class PersonOperations implements PersonOperationsI {


    public String getName() {
        return "";
    }

}

PersonOperationsConfigClass.java

package samples.chapter3;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
//question2  - Below Component Scan didnt work - Test Case failing in setup()
//@ComponentScan(basePackages = {"samples.chapter3"})
@EnableAspectJAutoProxy

public class PersonOperationsConfigClass {

}

PersonOperationsAdvice.java

/**
 * 
 */
package samples.chapter3;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class PersonOperationsAdvice {

    /**
     * execution( [Modifiers] [ReturnType] [FullClassName].[MethodName]
    ([Arguments]) throws [ExceptionType])

     * @param joinPoint
     * @return
     */
    @Before("execution(public * samples.chapter3.PersonOperations.getName()))")
    public String beforeGetName(JoinPoint joinPoint) {
        System.out.println("method name = " + joinPoint.getSignature().getName());
        return null;
    }
}

PersonOperationsTest.java

package samples.chapter3;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { PersonOperationsConfigClass.class })
public class PersonOperationsTest {

    //@Autowired
    private PersonOperationsI obj;

    @Before
    public void setUp() {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.scan("samples.chapter3");
        ctx.refresh();
        obj = ctx.getBean(PersonOperationsI.class);
//obj = ctx.getBean(PersonOperations.class);//getBean of Child class not working - why ?

        Assert.assertNotNull(obj);
        ctx.close();
    }

    @Test
    public void test() {
        System.out.println(obj.getName());
    }

}

質問1- @ componentscanが機能しない理由。テストケースでAnnotationConfigApplicationContextを使用せず、@ componentscanとautowiredに依存している場合、テストケースのオブジェクトはnullです。

質問2-子クラスのctx.getBean(PersonOperations.class); // getBeanが機能しない-なぜですか?

3 answers

1
user1234SI. 2020-01-16 17:11.
  1. 通常@ComponentScan@Configurationアノテーション付きクラスと一緒に使用する必要があります。引数なしの@ComponentScanは、現在のパッケージとそのすべてのサブパッケージをスキャンするようにSpringに指示することに注意してください

  2. @Componentクラスはとても不要になった使用のXML設定にそのタイプのBeanを作成するために春を告げる、そして豆は=>なしインターフェース/抽象クラスをインスタンス化することができるクラスです。したがって、あなたの場合は、@ Componentをから削除し、。PersonOperationsIにのみ残す必要がありPersonOperationsます。クラスに@Componentアノテーションを付ける場合、Beanに付けられるデフォルトの名前は、最初の文字が下のクラス名であるため、ctx.getBean("personOperationsI")またはを呼び出す必要があります。ctx.getBean(PersonOperations.class)

そして将来のために、インターフェースと実装のためのこれらの命名規則を読んでください。あなたの場合、私は以下を変更します:PersonOperationsItoOperations

1
Mehrdad HosseinNejad 2020-01-16 17:55.

質問2

あなたが言ったように、Beanスキャンプロセスは完了していなかったので、コンテキストにBeanなく、どちらの方法でもコンテキストからBeanを期待するべきではありません(どちらの方法もnullを返します)。@Autowiredcontext.getBean

以下のリンクには、Beanスキャンの詳細があります(役立つ場合があります)

Springコンポーネントのスキャン

1
R.G 2020-01-16 19:50.

A1、「ApplicationContextのロードに使用するコンポーネントクラス」@ComponentScanからコメントアウトされているため、機能しませんでした。またはPersonOperationsConfigClass

@Configuration
//@ComponentScan(basePackages = {"samples.chapter3"})
@EnableAspectJAutoProxy

public class PersonOperationsConfigClass {}

テストクラスは、@ ContextConfigurationアノテーションで指定されたコンポーネントクラスから作成されたApplicationContextを取得します。コンポーネントが作成されていないか、自動検出されていないため、@Autowired失敗しました。

AnnotationConfigApplicationContextアノテーションが付けられたメソッド内でが使用された場合@Before、ApplicationContextがプログラムで作成されました。ctx.scan("samples.chapter3");スキャンされ、。でPersonOperations注釈が付けられた自動検出@Componentobj参照はコードで設定されましたobj = ctx.getBean(PersonOperationsI.class);。このオブジェクトは「自動配線」ではありませんでした。

OPからのコメントに基づいて更新

Junit 4アノテーションと@ExtendWith(SpringExtension.class)の組み合わせが機能していません。

次のテストクラスは、エラー/失敗なしで正常に実行されます。obj自動配線され、nullではありません。Junit5の対応するアノテーションを使用しました。

package rg.app.aop.so.q1;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes= {PersonOperationsConfigClass.class})
public class PersonOperationsTest {

    @Autowired
    private PersonOperationsI obj;

    @BeforeEach
    public void setUp() {
        System.out.println("init ::"+ obj);
        Assertions.assertNotNull(obj);
    }

    @Test
    public void testPersonOps() {
        Assertions.assertNotNull(obj);
    }
}

構成クラス

package rg.app.aop.so.q1;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {"rg.app.aop.so.q1"})
public class PersonOperationsConfigClass {

}

A2、以下は私の分析です。

覚えておいてください、属性の@EnableAspectJAutoProxyデフォルト値は「false」proxyTargetClassです。この属性は、プロキシメカニズムを決定します:JDKプロキシ(false)またはCGLIBプロキシ(true)。

ここで、有効なアドバイスを持つ有効なアスペクトが存在すると、実際にプロキシが開始されます。コンポーネントは、アドバイスがそれに影響を与える場合にのみプロキシされます。つまり、コンポーネントのプロキシは、必要な場合にのみ発生します。

ケース1

いつ:@EnableAspectJAutoProxy/@EnableAspectJAutoProxy(proxyTargetClass = false )

  • ctx.getBean(InterfaceType) Beanを返します
  • ctx.getBean(ImplementationClassType) Beanを返さない

ケース2

いつ : @EnableAspectJAutoProxy(proxyTargetClass = true )

  • ctx.getBean(InterfaceType) Beanを返します
  • ctx.getBean(ImplementationClassType) Beanを返します

ケース3

いつ:@EnableAspectJAutoProxy注釈がない

  • ctx.getBean(InterfaceType) Beanを返します
  • ctx.getBean(ImplementationClassType) Beanを返します

ケース1、SpringAOPはproxyTargetClassfalseとして有効になっています。JDKプロキシは、インターフェースタイプのプロキシBeanを作成します。作成されるBeanのタイプはInterfaceTypeであり、ImplementationClassTypeではありません。これは、ctx.getBean(ImplementationClassType)がBeanを返さない理由を説明しています。

ケース2、SpringAOPはproxyTargetClasstrueとして有効になっています。CGLIBは、アノテーションが付けられたクラスをサブクラス化することによってプロキシBeanを作成し@Componentます。作成されたBeanはImplementationClassType型であり、InterfaceTypeとしての資格もあります。したがって、両方のgetBean()呼び出しは、このBeanを正常に返します。

ケース3

Springは、特別な処理が必要な場合にのみ「プロキシ」オブジェクトを作成します(例:AOP、トランザクション管理)。

このロジックでは、@EnableAspectJAutoProxyが存在し@Componentないため、プロキシなしでアノテーションが付けられたクラスに対してBeanが作成されます。作成されたBeanはImplementationClassType型であり、InterfaceTypeとしての資格もあります。したがって、両方のgetBean()呼び出しは、このBeanを正常に返します。

次のコードで分析を行います。

package rg.app.aop.so.q1;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AppMain {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.scan("rg.app.aop.so.q1");
        ctx.refresh();
        System.out.println();
        for(String name:ctx.getBeanNamesForType(PersonOperationsI.class)) {
            System.out.println(name);
        }
        for(String name:ctx.getBeanNamesForType(PersonOperations.class)) {
            System.out.println(name);
        }
        PersonOperationsI obj = ctx.getBean(PersonOperationsI.class);
        System.out.println(obj.getClass());

        obj = ctx.getBean(PersonOperations.class);
        System.out.println(obj.getClass());
        ctx.registerShutdownHook();

    }

}

ケース1のプリント

personOperations
class com.sun.proxy.$Proxy18
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'rg.app.aop.so.q1.PersonOperations' available

ケース2プリント

personOperations
personOperations
class rg.app.aop.so.q1.PersonOperations$$EnhancerBySpringCGLIB$$c179e7f2 class rg.app.aop.so.q1.PersonOperations$$EnhancerBySpringCGLIB$$c179e7f2

ケース3プリント

personOperations
personOperations
class rg.app.aop.so.q1.PersonOperations
class rg.app.aop.so.q1.PersonOperations

お役に立てれば

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

あなたが危険なほど過熱しているかどうかを知る方法

あなたが危険なほど過熱しているかどうかを知る方法

カリフォルニア州カレキシコでは、6月上旬に気温が約115度に達すると、人々はダウンタウンを歩きます。私たちは夏にたった2週間で、熱波はすでに米国を灼熱しています。

庵野秀明がシン・ウルトラマンのモーションキャプチャ俳優として最高の人生を送るのを見る

庵野秀明がシン・ウルトラマンのモーションキャプチャ俳優として最高の人生を送るのを見る

庵野秀明は、ついに新世紀エヴァンゲリオンを締めくくった後、自分のやりたいことを何でもしているようだ(少なくとも今のところ)。彼はウルトラマン映画を作るようになり、現在は仮面ライダー1号を監督しており、生涯にわたる2つのスーパーヒーローの執着のために新しい章を作成することを彼に任せています。

今週のおもちゃのニュースは間違いなくあなたのウーキーを曲げました

今週のおもちゃのニュースは間違いなくあなたのウーキーを曲げました

io9の最新かつ最高のオタク玩具ニュースの定期的なまとめであるToyAisleへようこそ。今週は、オビ=ワンの水曜日をさらに2つのハズブロフィギュアで締めくくります。Super7はスプリングフィールドに戻り、さらに多くのシンプソンズアルティメットを目指します。ダースベイダーをバップする勇気はありますか?見てみな!プレイメイトは、初期の頃からのシンプソンズのフィギュアの信じられないほど豊富なラインで素晴らしい仕事をしましたが、Super7のシンプソンズアルティメットほど詳細でアクセサリー化されていませんでした!数字—彼らがもっと早く彼らを追い出し始めてくれることを願っています。

ディズニーの不条理な$5,000スターウォーズカクテルの実際の内容は次のとおりです

ディズニーの不条理な$5,000スターウォーズカクテルの実際の内容は次のとおりです

その悪名高い5,000ドルのスターウォーズをテーマにした飲み物に何が入っているのか知りたいと思っているなら、それはもはや完全な謎ではありません。ハイパースペースラウンジのディズニーウィッシュクルーズ船で独占的に入手できるカイバークリスタルは、豪華に提示されたテーマカクテルで、提供されるカムトノに付属しているはずですが、残念ながらそうではありません。銀河系で最も高価なトップシェルフセレクション。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Seguindo Todos os Protocolos (2022), de Fábio Leal

Seguindo Todos os Protocolos (2022), de Fábio Leal

Chico quer transar. Até aí, tudo bem.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language