2015-12-19 23 views
6

私はゲッターとセッターといくつかの簡単なインターフェイスと、ファイルシステムから読み書きするいくつかのメソッドを持っています。 Javaコードを直接使用すると、1つの「呼び出しハンドラ」を作成して、これらのすべてのインタフェースのオブジェクトをインスタンス化することができます(試したことはありませんが、完了できたと思います)。Spring(AOP?)を使用してJavaインターフェイスを実装します

Springを使用して同じことを実行できるかどうかは疑問です。

以下のコードは、特定のインターフェイスを実装しています。同じインタフェースでも同じ呼び出しハンドラを使用することができます。

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 

public class AOPTester { 

    public static void main(String[] args) { 
     InvocationHandler handler = new MyInvocationHandler(); 
     AnyInterface proxy = (AnyInterface) Proxy.newProxyInstance(
            AnyInterface.class.getClassLoader(), 
            new Class[] { AnyInterface.class }, 
            handler); 

     proxy.sayHello(); 

    } 

} 

interface AnyInterface { 
    public void sayHello(); 
} 

class MyInvocationHandler implements InvocationHandler{ 

    public Object invoke(Object proxy, Method method, Object[] args) 
      throws Throwable { 
     System.out.println("Hello!"); 

     return null; 
    } 
} 
+0

ここに似た何か:[http://stackoverflow.com/questions/34133189/mongodb-dao-sets-all-attributes-to-null-before-save/34160666 ?noredirect = 1](http://stackoverflow.com/questions/34133189/mongodb-dao-sets-all-attributes-to-null-before-save/34160666?noredirect=1) – Valijon

+0

ごめんなさい@Valijon、私そのURLが何らかの形で私が何をする必要があるのか​​に関係しているのはなぜ分かりません。 –

+0

'Interfaces'はロジックを何もしません。サービスインタフェース契約を定義するだけです。したがって、まず、Javaコードでインタフェースの実装を定義する必要があります。次に、その実装を何度も開始したくない場合は、コンテキストから 'singleton'を取得できます。そのリンクには、「Dao」、「MongoOperations」のようないくつかのインターフェースがあり、そこから実装がコンテキストから回復されます。 Springは実装の構文を定義するのではなく、クラスを開始するのに役立ちます(バイトコードにコンパイルする方法は?) – Valijon

答えて

0

実際には、ProxyFactoryBeanを使用してSpringで行うためのきれいな方法があります。 以下の例では、このクラスはターゲットBeanなしで初期化されています。 作成されたオブジェクトには、要求を転送するターゲットはありませんが、Javaの他のプロキシと同様のインターフェイスを実装できます。

もちろん、MethodInterceptorのinvokeメソッドに渡された呼び出しオブジェクトでproceedメソッドを呼び出そうとすると、NullPointerExceptionが発生します。

より良いアプリケーションのcontext.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
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.2.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> 

    <bean id="goodbyeMethodInterceptor" class="com.someco.GoodbyeMethodInterceptor" /> 

    <bean name="goodbyeProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> 
     <property name="interfaces"> 
      <list> 
       <value>com.someco.AnyInterface</value> 
      </list> 
     </property> 
     <property name="interceptorNames"> 
      <list> 
       <value>goodbyeMethodInterceptor</value> 
      </list> 
     </property> 
    </bean> 
</beans> 

GoodbyeMethodInterceptor:

package com.someco; 

import org.aopalliance.intercept.MethodInvocation; 

public class GoodbyeMethodInterceptor implements org.aopalliance.intercept.MethodInterceptor { 

    public Object invoke(MethodInvocation invocation) throws Throwable { 
     System.out.println("Goodbye"); 

     return null; 
    } 

} 

ProxyTester:

package com.someco; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

import com.someco.AnyInterface; 

public class ProxyTester { 

    public static void main(String[] args) { 
     ApplicationContext context = new ClassPathXmlApplicationContext("better-application-context.xml"); 
     AnyInterface tester = (AnyInterface) context.getBean("goodbyeProxy"); 
     tester.sayHello(); 
    } 
} 

AnyInterface:

package com.someco; 

public interface AnyInterface { 
    public void sayHello(); 
} 

基本のpom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.someco</groupId> 
    <artifactId>proxy-tester</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>main</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <spring.version>3.0.5.RELEASE</spring.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
    </dependencies> 
</project> 
2

次の設定が有効です(クラスを使用しましたが、コードを読みやすくするために別のパッケージに移動しました)。 私は、使用したファクトリメソッドnewProxyInstance()と同じ呼び出しを実行するためにスプリングコンテキストを使用しました。

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
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.2.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> 

    <bean id="pojoInvocationHandler" class="com.someco.PojoInvocationHandler"></bean> 

    <bean id="AnyInterfaceClass" class="java.lang.Class" factory-method="forName"> 
     <constructor-arg value="com.someco.AnyInterface"/> 
    </bean> 

    <bean id="anyInterface" class="java.lang.reflect.Proxy" factory-method="newProxyInstance"> 
     <constructor-arg> 
      <bean 
       factory-bean="AnyInterfaceClass" 
       factory-method="getClassLoader" /> 
     </constructor-arg> 
     <constructor-arg> 
      <list> 
       <ref bean="AnyInterfaceClass" /> 
      </list> 
     </constructor-arg> 
     <constructor-arg ref="pojoInvocationHandler"/> 
    </bean> 
</beans> 

ProxyTester:

package com.someco; 

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Proxy; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

import com.someco.AnyInterface; 

public class ProxyTester { 

    public static void main(String[] args) { 
     ApplicationContext contex = new ClassPathXmlApplicationContext("application-context.xml"); 
     AnyInterface tester = (AnyInterface) contex.getBean("anyInterface"); 
     tester.sayHello(); 

     /* Implemented with the previous code */ 
//  callProxy(); 
    } 

    /** 
    * @deprecated 
    * explanation of why function was deprecated, if possible include what 
    * should be used. 
    */ 
    @Deprecated 
    public static void callProxy() { 
     InvocationHandler handler = new PojoInvocationHandler(); 
     AnyInterface proxy = (AnyInterface) Proxy.newProxyInstance(
            AnyInterface.class.getClassLoader(), 
            new Class[] { AnyInterface.class }, 
            handler); 
     proxy.sayHello(); 
    } 

} 

PojoInvocationHandler:

package com.someco; 

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 

public class PojoInvocationHandler implements InvocationHandler{ 

    public Object invoke(Object proxy, Method method, Object[] args) 
      throws Throwable { 
     System.out.println("Hello!"); 

     return null; 
    } 
} 

AnyInterface:

package com.someco; 

public interface AnyInterface { 
    public void sayHello(); 
} 

基本のpom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.someco</groupId> 
    <artifactId>proxy-tester</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>main</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <spring.version>3.0.5.RELEASE</spring.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
    </dependencies> 
</project> 
+2

これはもっとコンパクトな構成を探していても有望です。 –

+2

"AnyInterfaceClass"と呼び出しハンドラの2つのパラメータのみを持つ静的メソッドを持つクラスを実装できます。これは私が自分のために試みることです。 –

+2

ありがとう!私は誰かがより良い解決策を持っているかどうかを確かめるために、答えとして質問を設定しません。 –

関連する問題