【问题标题】:Aspect Oriented Programming in Java WITHOUT AspectJ?没有 AspectJ 的 Java 中的面向方面编程?
【发布时间】:2014-06-13 04:11:34
【问题描述】:

好的,这个问题以前从未在网络上被问过,所以这里是: 我正在学习 Java(初中级),我决定通过尝试面向方面的编程来领先于课堂课程。

现在这东西应该很容易学习(至少这是网络共识) 以至于“方面”据说是标准类的略微修改版本, 所以我的问题是:如果方面基本上是类,

为什么我们必须安装 AspectJ 才能在 Java 中进行 AOP?

因为这只是增加了一层额外的复杂性,使这个概念更难掌握。

我想要的是能够在不使用 AspectJ(或任何其他附加组件)的情况下编写一个方面,换句话说,我想只使用 BASIC Java 及其标准 Java 类来执行 AOP。有可能吗?如果可以,我该如何编写这些类?

【问题讨论】:

  • 当然可以。你甚至不需要另一个框架(比如 Spring AOP)。在时间的考验中,AspectJ 顺便也未能获得动力。例如,属性 + 反射可以成为为框架执行 AOP 的一种方式。
  • 是的好问题..我们可以编写反射类型的代码并使用正则表达式根据之前、之后和周围的指令调用方法..我们可以解决它但需要更多时间。 .
  • 感谢各位。看起来我还有很长的路要走,因为反射和这样的(与内省有关)暂时超出了我的范围。大声笑我想问我的问题的另一种方式是,如何将(简单)AspectJ 编码的程序转换为纯 Java 程序,并且尽可能少地进行修改?

标签: java aop


【解决方案1】:

Java 不支持开箱即用的 AOP,我不建议您自己实现它,因为您必须在加载类文件时修改它们。或者,您也可以修改编译好的类文件,但这会更加复杂。

AspectJ 使用 Java 代理来设置编织类加载器(它会在加载时修改类文件),但您也可以手动使用自己的类加载器。如果您要修改的类都实现了一个接口,那么您可以将Java Proxies 用于AOP。否则,您将不得不使用外部库,如 CGLib、Javassist 或 ASM(或了解 Java 字节码的工作原理)。

一些进一步的信息:

代理示例:

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

public class ProxyExample {

    public static void main(String[] args) {
        AnInterface obj = new AClass();
        AnInterface proxyObj = createProxy(obj);
        System.out.println(obj.aMethod());
        System.out.println(proxyObj.aMethod());
    }

    private static AnInterface createProxy(AnInterface obj) {
        return (AnInterface) Proxy.newProxyInstance(ProxyExample.class.getClassLoader(),
                new Class<?>[] {AnInterface.class},
                new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return "proxy: " + method.invoke(obj);
            }
        });
    }

    static interface AnInterface {
        public String aMethod();
    }

    static class AClass implements AnInterface {
        @Override
        public String aMethod() {
            return "string";
        }
    }

}

【讨论】:

  • 好的,谢谢! java代理超出了我的能力(我知道的唯一“代理”是使用另一个IP通过我的网络请求来隐藏我自己的IP。我不知道这两个概念是否相关,因为我见过这个词“代理”用于许多不同的领域,令人困惑:/)
  • @user3578836,我刚刚添加了一个代理示例。在这种情况下,代理是指一个可以代理方法调用另一个对象的对象。
【解决方案2】:

AspectJ 是一个“纯粹的”Aspect 框架,因为没有更好的词。标准是它可以在各种情况下广泛使用。任何方面,任何课程,任何时间。

也就是说,拦截和包装方法调用的切面技术已经在 J​​ava 中普遍存在。然而,这些趋向于将通用方面概念专门化以用于特定目的。

一个非常早期的“方面”是用早期的 EJB 功能完成的。这需要使用 XML 文件来扩充类和接口,以便容器可以创建代理对象,将方法调用包装到事务上下文中。方法的这种包装是一个方面的概念,但早期的 EJB 规范只提供了非常具体的事务管理用例的功能。

Java 1.5 中注释的出现开启了面向方面编程的这种扩展概念。这并不是说您需要注释来实现这一点,而是它只是使框架更易于使用,因为注释消除了外部元数据配置(可能使用 XML 文件)。

因此,现在,许多 Java 系统使用来自面向方面编程的概念,通常通过反射和注释来实现某些功能。这是否是实例注入,围绕方法,验证等。

这一切的关键组成部分是一些拦截方法调用的机制。 AspectJ 通过动态更改目标类而不是插入中间人来工作。 EJB 通过在接口上创建代理(您可以在 Java 中开箱即用)来工作,然后当程序向容器请求实例时,它会提供由实际实例支持的代理。

因此,要随时随地启用“通用”AOP,您当然需要像 AspectJ 这样范围广泛的东西。但要获得它的大部分好处,你不需要走那么远。一个简单的工厂类和一个接口就可以轻松完成这项工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 2010-11-24
    • 2010-09-18
    • 2012-09-03
    • 2010-09-08
    • 2011-06-29
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多