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

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

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

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

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

バレリー・ジャレットは類人猿と呼ばれ、ロザンヌ・バーは仕事を失いましたが、ここでの本当の犠牲者はトランプです

バレリー・ジャレットは類人猿と呼ばれ、ロザンヌ・バーは仕事を失いましたが、ここでの本当の犠牲者はトランプです

ロザンヌ・バーが自分自身でいるだけでABCショーの再起動を破壊するのに、60日強かかりました。ロザンヌは、ツイッターで帽子をかぶったトロールであり、白人至上主義者に傾倒し、陰謀論者を愛する「Make AmericaGreatAmerica」であり続けています。

「警察官」を使用して、ビジネス会議をトピックに保つ

「警察官」を使用して、ビジネス会議をトピックに保つ

仕事の打ち合わせをしていると、招待される人が多ければ多いほど、全体が狂いやすくなります。そのため、すべての打ち合わせには、話題を維持するための打ち合わせ「警察」が必要です。全員が集まって話し合う間今週終了する大きなプロジェクトについては、必然的に誰かが「私たちはみんなここにいるので…」と決めるでしょう。数週間後に起こっている別のプロジェクトを立ち上げるのは良い考えです。コーヒーメーカーはどうしたの?壊れていますか?そして、ジョンの新しい子犬を見たことがありますか?会話を中断して、10分間写真を見てみましょう。

黒人が記念日を作成—文字通り

黒人が記念日を作成—文字通り

記念日はここにあります。バーベキュー、レモネードを考えてください。

ドレイク、ネコケース、そしてカニエの大洪水:6月の38の最も期待されたアルバム

ドレイク、ネコケース、そしてカニエの大洪水:6月の38の最も期待されたアルバム

5月のリリースの特に強力なラインナップに続いて、6月はNeko Case、Nas、Lykke Li、Gang Gang Danceから待望のリターンをもたらし、Drake、Oneohtrix Point Never、Zeal&Ardourからの期待された努力とSnailMailからの有望なデビューをもたらしますとジュリアーナドーティ。ヒップホップでは、間違いなくカニエの月であり、ラッパープロデューサーは毎週少なくとも1回のリリースに関与しています。

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。

コンセプト ドリフト: AI にとって世界の変化は速すぎる

コンセプト ドリフト: AI にとって世界の変化は速すぎる

私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

犯罪擁護派のオークランドが暴力犯罪者のロミオ・ロレンゾ・パーハムを釈放

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

Language