2015-12-19 6 views
6

का उपयोग कर रहा getters और setters और कुछ अन्य तरीकों के साथ कई सरल इंटरफेस पढ़ सकते हैं और फाइल सिस्टम से लिखने के लिए है लागू करता है। सीधे जावा कोड का उपयोग करके, मैं एक "आमंत्रण हैंडलर" लिख सकता हूं और इन सभी इंटरफेस के लिए ऑब्जेक्ट्स को तुरंत चालू करने के लिए इसका उपयोग कर सकता हूं (मैंने कोशिश नहीं की है, लेकिन मुझे लगता है कि यह किया जा सकता है)।एक जावा इंटरफ़ेस स्प्रिंग (AOP?)

मुझे आश्चर्य है कि वसंत का उपयोग करके ऐसा करना संभव है या नहीं।

नीचे दिया गया कोड, दिए गए इंटरफ़ेस को लागू करता है। जैसा कि आप आसानी से देख सकते हैं, वही उसी आमंत्रण हैंडलर का उपयोग किसी भी इंटरफ़ेस के लिए किया जा सकता है।

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, मैं यह न देखें कि उस यूआरएल को किसी भी तरह से संबंधित होना चाहिए जो मुझे करना है। –

+0

'इंटरफेस' कोई तर्क नहीं करता है, बस सेवा इंटरफ़ेस अनुबंध को परिभाषित करें।तो, सबसे पहले, आपको जावा कोड में इंटरफ़ेस कार्यान्वयन को परिभाषित करने की आवश्यकता है। फिर, यदि आप कई बार उस कार्यान्वयन को शुरू नहीं करना चाहते हैं, तो आप संदर्भ से 'सिंगलटन' पुनर्प्राप्त कर सकते हैं। उस लिंक में, कई इंटरफेस हैं, जैसे 'दाओ', 'मोंगोऑपरेशंस' जहां कार्यान्वयन संदर्भ से पुनर्प्राप्त किया गया है। वसंत सिर्फ आपको अपनी कक्षाएं शुरू करने में मदद करता है, कार्यान्वयन वाक्यविन्यास को परिभाषित नहीं करता है (यह बाइट कोड में कैसे संकलित होगा?) – Valijon

उत्तर

0

वास्तव में ProxyFactoryBean का उपयोग करके वसंत के साथ ऐसा करने का एक साफ तरीका है। नीचे दिए गए उदाहरण में इस वर्ग को लक्ष्य बीन के बिना शुरू किया गया है। बनाए गए ऑब्जेक्ट में अनुरोधों को आगे बढ़ाने का कोई लक्ष्य नहीं है, लेकिन यह किसी भी इंटरफ़ेस को जावा में किसी भी अन्य प्रॉक्सी जैसे कार्यान्वित कर सकता है।

बेशक, यदि आप MethodInterceptor की चालक विधि को पारित आमंत्रण ऑब्जेक्ट पर कार्यवाही विधि को कॉल करने का प्रयास करते हैं, तो आपको एक 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

धन्यवाद! मैं इस सवाल को उत्तर के रूप में सेट नहीं करूँगा कि यह देखने के लिए कि क्या कोई बेहतर समाधान है या नहीं। –

संबंधित मुद्दे