Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 野外春景_Java_Spring_Aspectj - Fatal编程技术网

Java 野外春景

Java 野外春景,java,spring,aspectj,Java,Spring,Aspectj,我要向XDB汇报一件事。数据库在表INFLUX_DB_服务器中注册了influxdb。如果您查看代码,您将看到reportMemory方法做了大量工作,它构造了一个度量并调用reportAll,当没有xdb时,所有这些工作都是无用的 因此,如果没有XDB,我们可以跳过这项工作。由于public void方法不返回值,因此对周围的应用程序没有影响 我能做的就是写一个方法isworkable,每次调用都调用这个方法。这可能是接吻之后的事,但这是干的。所以我喜欢用AOP来归档 但是如果没有注册XDB,

我要向XDB汇报一件事。数据库在表INFLUX_DB_服务器中注册了influxdb。如果您查看代码,您将看到reportMemory方法做了大量工作,它构造了一个度量并调用reportAll,当没有xdb时,所有这些工作都是无用的

因此,如果没有XDB,我们可以跳过这项工作。由于public void方法不返回值,因此对周围的应用程序没有影响

我能做的就是写一个方法isworkable,每次调用都调用这个方法。这可能是接吻之后的事,但这是干的。所以我喜欢用AOP来归档

但是如果没有注册XDB,我喜欢跳过所有公共void方法的执行

/**
 * The reporter to notify {@link InfluxDB influxDBs} for changes.
 */
@Named
public class InfluxDBReporter {
    /**
     * Logger for reporting. For security reasons neither the username nor the
     * password should be logged above {@link Level#FINER}.
     */
    private static final Logger LOG = Logger.getLogger(InfluxDBReporter.class.getCanonicalName());

    /**
     * The entitymanager to use, never <code>null</code>.
     */
    @PersistenceContext
    private final EntityManager entityManager = null;

    /**
     * The registred {@link InfluxDBServer} in key and the URL in value.
     */
    @SkipPublicVoidMethodsIfEmpty
    private final Map<InfluxDB, URL> dbs = new LinkedHashMap<>();

    /**
     * Initializes the connections.
     */
    @PostConstruct
    private void connect() {
        for (InfluxDBServer db : FROM(囗InfluxDBServer.class).all(entityManager)) {
            try {
                URL dbUrl = new URL(db.getUrl());
                InfluxDB idb = InfluxDBFactory.connect(db.getUrl(), db.getUsername(), db.getPassword());
                idb.setDatabase(db.getDatabaseName());
                dbs.put(idb, dbUrl);
            } catch (MalformedURLException e) {
                LOG.log(Level.SEVERE, db.getUrl(), e);
            }
        }
    }

    /**
     * Closes all connections to all {@link InfluxDB}.
     */
    @PreDestroy
    private void disconnect() {
        for (InfluxDB influxDB : dbs.keySet()) {
            try {
                influxDB.close();
            } catch (Exception e) {
                // Fault barrier
                LOG.log(Level.WARNING, "InfluxDBServer URL: " + dbs.get(idb), e);
            }
        }
    }

    /**
     * Report memory statistics.
     * 
     * @param availableProcessors Amount of available processors, never negative.
     * @param totalMemory         The total memory, never negative.
     * @param maxMemory           The max memory, never negative.
     * @param freeMemory          The free memory, never negative.
     */
    public void reportMemory(int availableProcessors, long totalMemory, long maxMemory, long freeMemory) {
        reportAll(Point.measurement("jvm").addField("totalMemory", totalMemory).addField("maxMemory", maxMemory)
                .addField("freeMemory", freeMemory));
    }

    /**
     * Report a point to all connected {@link InfluxDBServer}.
     * 
     * @param builder The point to report.
     */
    private void reportAll(Builder builder) {
        Point infoPoint = builder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).build();
        for (InfluxDB idb : dbs.keySet()) {
            new Thread(() -> {
                try {
                    idb.write(infoPoint);
                } catch (Exception e) {
                    // Fault barrier
                    LOG.log(Level.WARNING, "InfluxDBServer URL: " + dbs.get(idb), e);
                    throw e;
                }
            }).start();
        }
    }
}
这是我的观点:

@Aspect
public class MethodAnnotations {
    @Pointcut("@annotation(xxx.MethodAnnotations.SkipPublicVoidMethodsIfEmpty)")
    private void anyOldTransfer(JoinPoint jp) {
        System.out.println(jp); <----- never executed.
    }

    public @interface SkipPublicVoidMethodsIfEmpty {
    }
}
我希望System.out.println在bean被实例化时运行,但它没有

知道为什么吗?

正如JB Nizet已经说过的,@annotationmy.package.MyAnnotation旨在捕获方法上的注释,而不是字段上的注释,这解释了为什么您对发生任何事情的期望是错误的

如果您想通过AOP发现一个类是否有一个带有特定注释的成员,那么需要使用一个特殊的切入点,如hasfield@MyAnnotation * *. 但是这个切入点在SpringAOP中是不可用的,您需要这样做。如果您希望通过拦截对此类字段的读/写访问,则情况也是如此get@MyAnnotationMyType*或set@MyAnnotationMyType*

有关更多详细信息,请参阅

AspectJ还提供了特殊的切入点

在类加载->staticinitialization之后拦截类的静态初始化 拦截构造函数执行->MyType.new 您可以在适当的时候使用它们来执行方面建议。在您的示例中,如果很明显所有目标类都有@PostConstruct方法中的一个,那么您还可以更容易地钩住@PostConstruct方法

我的回答相当笼统,因为你没有详细解释你到底想做什么。因此,请随时提出后续问题

更新:我查看了你最新的问题更新。我不明白,对于一个非常简单的问题,这是一个非常做作的解决方案,也不是AOP可以解决的好案例。尽管我非常喜欢AOP,但我无法理解这种情况是如何成为一个贯穿各领域的问题:

它似乎只影响到一个类,即Breporter。 您正在使用一个注释,该注释的唯一目的是告诉一个方面要做什么。 更糟糕的是,您将注释放在一个私有字段上,但期望外部类(在本例中是一个方面)对其作出反应。虽然AspectJ在技术上可以做到这一点,但这是一种糟糕的设计,因为您正在将私有信息泄露给外部。 通过从示例类中跳过public方法,您不会保存任何昂贵的与DB相关的操作,因为对空键集进行迭代意味着什么也不会发生,因此也不会出现任何与DB相关的错误。这里唯一真正发生的事情是生成器调用。它们应该便宜。 即使假设您有更多应该跳过的公共方法,如果您确实想坚持这种方法,我也会像这样设计AOP解决方案:

向应用程序类中添加一个方法public boolean isConnectedToDB{return!dbs.isEmpty;}。 在您的方面中,使用@Around建议并从那里调用布尔方法,仅在存在任何连接时调用joinPoint.continue。否则,不要继续,而是对void方法不执行任何操作,或者对非void方法返回类似null的伪结果。 确切的解决方案取决于您是否只有一个类或多个具有类似需求的类,如果您只有公共的void方法或非void方法

此外,您提到了influxdb\u服务器,但我不知道这是什么,因为我在代码中的任何地方都看不到它


最后,但并非最不重要的一点:我刚刚注意到,您希望在@Pointcut注释的方法中发生一些事情。抱歉,即使切入点没有错,也会发生这种情况,因为切入点定义只是用于实际的通知方法中,例如@Before、@After、@Around。您希望执行的操作进入通知,而不是切入点。我建议您在尝试设计基于AOP的解决方案之前先学习AOP基础知识。

来自文档:@annotation:限制匹配到连接点,其中连接点的主题Spring AOP中执行的方法具有给定的注释。我没有看到SkipMethodsOne在任何地方使用。我没有看到SkipPublicVoidMethodsIfEmpty用于任何方法。你为什么有这样的期望?为什么Spring应该关心放在一些不相关字段上的不同注释?你想实现什么?啊,我将SkipMethodSoneEmpty重命名为SkipPublicVoidMethodsIfEmpty,但忘了更新切入点表达式。我真蠢!更新问题。但事实是@annotationmy.package.MyAnnotation不影响字段
. 这对我来说是个糟糕的晚餐!好的,它是有文档记录的,所以如果你读过SpringAOP手册,这应该不会令人惊讶。我希望JavaDoc中会出现hat异常,但在相关位置找不到它。这样问比较容易。是一名布莱维斯特,而你是AspectJ教练,我为什么不向你学习呢-你指的是用户手册,不是Javadoc。这就是您要链接到的内容。忽略链接到非常旧版本Spring 2.5的事实,但如果搜索第一次出现的@annotation,您仍然会清楚而简洁地发现根本没有Bleiwüste声明:限制匹配到Spring AOP中执行的连接点方法的主题具有给定注释的连接点。请注意我的答案更新后,您的问题更新。囗InfluxDBServer是来自jdbc人工桥的表influxdb_服务器的实体。根据您的建议,在每个公共void方法上重复@Around将违反DRY。