2017-01-04 5 views
0

私は非常に単純なプラグインアーキテクチャを持ち、Springクラスパススキャンを使って追加の動作を登録する手段を持っています(plugin.jarをクラスパスに置くことによってプラグインがインストールされます)。クラスパススキャンを使用して定義されたSpring Bean定義を上書きできますか?

これは、追加の豆を登録するための素晴らしい作品、それはまた、このようなフックを登録するための素晴らしい作品:

// core.jar: 
@Component 
class CoreClass { 
    public void addListener(Listener listener) { /* ... */ } 
} 

// plugin.jar 
@Component 
class Plugin { 
    public Plugin(CoreClass coreClass) { 
    coreClass.addListener(new PluginListener()); 
    } 
} 

は、しかし、時には全体の豆を交換するために、より適切です。これは、次のようになります。

// core.jar: 
@Component("someBean") 
class CoreClass implements CoreInterface { 
    @Override 
    public void doStuff(); 
} 

// plugin.jar 
@Component("someBean") 
@Order(HIGHEST_PRECEDENCE) 
class Plugin implements CoreInterface { 
    @Override 
    public void doStuff(); 
} 

を私は両方PluginCoreClassは、起動時にクラスパスのスキャンによって発見されているが、その後CoreClassを無視するようにしたい。この場合、豆someBeanは、優先順位の高い別の定義を持っているので。

私はXML(<import resource="classpath*:plugin-spring.xml" />)を使用してこれを行うことができることを知っています。なぜなら、XMLはオーバーライド定義を可能にするからです。しかし、アノテーションを使用してこれも可能ですか?

編集:時々、私は名前ベースのものを注入する同じタイプ(異なる特性を持つ)の複数のBeanインスタンスを持っていることに注意してください。したがって、実際には特定の名前でBeanをオーバーライドする必要があります。使用する

答えて

0

考えられる解決策:

@Primary

複数の候補が単一値の依存性をautowireするために認定されていたときにBeanが優先されるべきであることを示します。正確に1つの「プライマリ」Beanが候補の中に存在する場合、それは自動値になります。

このアノテーションは、Spring XMLの要素のプライマリ属性と意味的に同等です。

@Componentで直接的または間接的に注釈を付けられたクラス、または@Beanで注釈が付けられたメソッドで使用できます。

// core.jar: 
@Component 
class CoreClass implements CoreInterface { 
    @Override 
    public void doStuff(); 
} 

// plugin.jar 
@Component 
@Primary 
class Plugin implements CoreInterface { 
    @Override 
    public void doStuff(); 
} 

http://memorynotfound.com/handling-multiple-autowire-candidates-with-spring-primary/

それとも、使用することができます

@Configuration 
@ImportResource({ "classpath*:core-spring.xml", "classpath*:plugin-spring.xml" }) 
public class ConfigClass { } 

は私が注釈でその問題があると思われるが、あなたが終わるアップします記法同じ名前の上に定義した場合、上書きしたため明確ではありません ConflictingBeanDefinitionException春の場合は、 @Componentまたは @Beanと同じ名前を使用できません。 xmlでは、オーバーライド注文を管理することができます。これはxmlでこれを行う理由です。アノテーションでは、それを行うことはできません。

任意指定任意のIDまたは名前に対して1つのBeanのみを持つことができます。。 XML id属性の場合、これはスキーマの検証によって強制されます。 name属性の場合、これはSpringのロジックによって強制されます。

しかし、コンテキストが2つの異なるXML記述子ファイルから構成され、idが両方のファイルで使用されている場合、一方が他方を上書きします。正確な動作は、コンテキストによってロードされるときのファイルの順序に依存します。

だから、それが可能だが、それはお勧めしません。エラーが発生しやすく、壊れやすいので、IDのIDを変更するとSpringの助けを借りることはできません。

しかし、コンテキストが2つの異なるXML記述子ファイルから構成され、idが両方のファイルで使用されている場合、一方が他方を上書きします。正確な動作は、コンテキストによってロードされるときのファイルの順序に依存します。

+0

真、一次はあなたが上記示しケース(タイプベースの注射)で動作します。しかし、私の場合、私は名前に基づいて注入する特定のタイプの複数のインスタンスを持つことがよくあります。しかし、@Primaryでは、同じ名前の2つのBeanを定義することはできません。 – yankee

+0

私はあなたが春になる予定のものを何かしようとしていると思う。私の提案は '@ Primary'と' @ Qualifier'を使って別のBeanが必要なところです。 –

関連する問題