1 回答
TA贡献1802条经验 获得超5个赞
正如JB Nizet已经说过的那样,@annotation(my.package.MyAnnotation)
它旨在捕获方法上的注释,而不是字段上的注释,这解释了为什么您对任何事情发生的期望都是错误的。
如果你想通过 AOP 找出一个类是否有一个带有特定注释的成员,你需要使用一个特殊的切入点,比如hasfield(@MyAnnotation * *)
. 但是这个切入点在 Spring AOP 中不可用,你需要切换到 AspectJ。get(@MyAnnotation MyType *)
如果您想通过或拦截对此类字段的读/写访问,也是如此set(@MyAnnotation MyType *)
。
AspectJ 还提供了特殊的切入点
在类加载后拦截类的静态初始化 - >
staticinitialization()
拦截构造函数执行->
MyType.new()
只要是合适的时间,您就可以使用它们来执行您的方面建议。@PostConstruct
在您的示例中,如果很明显所有目标类都有其中一个,您还可以更轻松地挂接到方法中。
我的回答很笼统,因为你没有详细解释你到底想做什么。所以请随时提出后续问题。
更新:我检查了你最新的问题更新。我不明白,这是针对一个非常简单的问题的非常人为的解决方案,也不是 AOP 解决的好案例。尽管我很喜欢 AOP,但我看不出这种情况是一个横切关注点:
它似乎只影响一个类,
InfluxDBReporter
.您正在使用一个注释,该注释的存在唯一目的是告诉一个方面要做什么。
更糟糕的是,您将注释放在私有字段上,但期望外部类(在本例中为方面)对其作出反应。虽然这在技术上使用 AspectJ 是可行的,但它是糟糕的设计,因为您将私有信息泄漏到外部。
通过从您的示例类中跳过公共方法,您不会保存任何昂贵的与数据库相关的操作,因为迭代一个空
KeySet
意味着什么都不会发生,因此也不会有任何与数据库相关的错误。这里唯一真正发生的是构建器调用。它们应该很便宜。
即使假设你有更多应该跳过的公共方法,如果你确实想坚持使用这种方法,我实际上会设计这样的 AOP 解决方案:
向您的应用程序类添加一个方法
public boolean isConnectedToDB() { return !dbs.isEmpty(); }
。在您方面,使用
@Around
建议并从那里调用布尔方法,仅joinPoint.proceed()
在有任何连接时才调用。否则不要继续,而是什么也不做(对于void
方法)或返回一个虚拟结果null
(对于非void
方法)。
确切的解决方案取决于您是否只有这个类或多个具有类似要求的类,如果您只有public void
方法或非空方法。
此外,您提到INFLUX_DB_SERVER
但我不知道这是什么,因为我在您的代码中的任何地方都看不到它。
最后但并非最不重要的一点是:我刚刚注意到您希望在 . 注释的方法中发生某些事情@Pointcut
。抱歉,即使切入点没有错,那里也会发生一些事情,因为切入点定义只是用于实际的建议方法,例如@Before
, @After
, @Around
。您想要执行的操作进入通知,而不是进入切入点。我建议您在尝试设计基于 AOP 的解决方案之前先学习 AOP 基础知识。
添加回答
举报