2012-09-19 66 views
5

有一個在我們要訪問的運行時間Tomcat引擎的一些信息,所以在我們的應用程序方面,我們有以下幾點(得到這個來自this blog post):如何將代理注入服務?

<bean id="tomcatEngineProxy" class="org.springframework.jmx.access.MBeanProxyFactoryBean"> 
    <property name="objectName" value="Catalina:type=Engine" /> 
    <property name="proxyInterface" value="org.apache.catalina.Engine" /> 
    <property name="useStrictCasing" value="false" /> 
</bean> 

在控制器中,我們則自動裝配它像這樣:

@Autowired 
private MBeanProxyFactoryBean tomcatEngineProxy = null; 

我們不能絲org.apache.catalina.Engine喜歡在博客文章,因爲那類不提供給我們在構建時。它僅在運行時纔可用,所有不同的tomcat版本都運行在不同的機器上。

我們能夠使用反射從@Autowire獲取所需的信息。現在,我們希望將此功能轉移到服務中。我將此添加到我們的應用程序上下文:

<bean id="myService" class="com.foo.bar.MyServiceImpl"> 
    <constructor-arg ref="tomcatEngineProxy" /> 
</bean> 

和類看起來是這樣的:

public class MyServiceImpl implements MyService 
{ 
    public MyServiceImpl(MBeanProxyFactoryBean tomcatEngineProxy) throws Exception 
    { 
     //stuff with the proxy 
    } 
    ..... 
} 

當我這樣做,我得到以下錯誤:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myService' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.jmx.access.MBeanProxyFactoryBean]: Could not convert constructor argument value of type [$Proxy44] to required type [org.springframework.jmx.access.MBeanProxyFactoryBean]: Failed to convert value of type '$Proxy44 implementing org.apache.catalina.Engine,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'org.springframework.jmx.access.MBeanProxyFactoryBean'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [$Proxy44 implementing org.apache.catalina.Engine,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.jmx.access.MBeanProxyFactoryBean]: no matching editors or conversion strategy found 

知道基本上沒什麼關於代理如何工作以及如何使用它們,我不知道如何去做這項工作。有我可以使用我的構造函數arg將匹配的一些聲明?執行工作的控制器中的@Autowire和不起作用的構造函數arg有什麼不同?

回答

4

這是因爲你的工廠bean被暴露結果作爲引擎接口:

<property name="proxyInterface" value="org.apache.catalina.Engine" /> 

所以,如果你試圖線在「tomcatEngineProxy」豆本身,它只是兼容的任務是「org.apache。 catalina.Engine「,因爲創建的代理僅實現該接口。

嘗試引用該工廠bean,而不是直接(注意符號這對尋找其創建的對象,而不是對象本身的實際工廠bean的語法):

<constructor-arg ref="&tomcatEngineProxy" /> 

How to inject FactoryBean instead of object it produces?

+0

完美!像魅力一樣工作。我以前沒有看過這種語法。我確實需要這樣做:'',但這只是讓XML感到高興的問題。謝謝! – dnc253

+0

np。只是不要在EL表達式中嘗試它,因爲它已經壞了:)我有一個錯誤來解決這個問題。 – Matt

0

我相信按照Bean(即MBeanProxyFactoryBean)的類型,由於結合@Autowired作品完成,然而,構造函數參數的綁定是通過名字和你所提供tomcatEngineProxy的名稱不匹配你所期望的類型因爲使用FactoryBean創建的bean的類型不同於FactoryBean

它看起來像最簡單的解決方案將是改變MyServiceImpl是:

public class MyServiceImpl implements MyService 
{ 
    @Autowired 
    private MBeanProxyFactoryBean tomcatEngineProxy; 

    public MyServiceImpl() throws Exception 
    { 
     //stuff with the proxy 
    } 
    ..... 
} 

這應該做的伎倆。

+0

正如我所說上面,我們沒有org.apache.catalina.Engine在構建時可用。使其可用將與我們構建的任何版本的tomcat綁定,並且我們在所有不同的服務器上運行不同版本的tomcat。我不知道如何,但控制器中的自動裝配肯定有效。 – dnc253

+0

@ dnc253:對不起 - 我錯過了那部分問題。 – RonK