使用Spring实现Java接口(AOP?)

8 java aop spring

我有几个简单的接口,包括getter和setter,还有一些其他方法可以从文件系统中读取和写入.直接使用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;
    }
}   
Run Code Online (Sandbox Code Playgroud)

Mar*_*eri 0

实际上,有一种使用 Spring 的 ProxyFactoryBean 的干净方法可以做到这一点。在下面的示例中,此类在没有目标 bean 的情况下进行初始化。创建的对象没有任何转发请求的目标,但它可以像 Java 中的任何其他代理一样实现任何接口。

当然,如果您尝试在传递给 MethodInterceptor 的 invoke 方法的调用对象上调用proceed 方法,您将得到 NullPointerException。

更好的应用程序上下文.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>
Run Code Online (Sandbox Code Playgroud)

再见方法拦截器:

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

代理测试器:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

任意接口:

package com.someco;

public interface AnyInterface {
    public void sayHello();
}
Run Code Online (Sandbox Code Playgroud)

基本的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>
Run Code Online (Sandbox Code Playgroud)