我之前曾使用 AOP 风格的代码将逻辑与日志记录分开,并且对结果非常满意。我认识到对 AOP 的看法各不相同,但我想在 Elixir 中找到一个解决方案,即使我最终没有在产品中使用它。
我见过的最接近的例子是 ExUnit 内部的设置回调,它允许在每个测试运行之前执行代码;我想做类似的事情,但无法通过 ExUnit 源代码来掌握那里的直觉。
以代码形式:
defmodule Project.Logic do
LoggingInjection.inject Project.Logging
def work_do_stuff(arg) do
#...
#returns some_result
end
end
Run Code Online (Sandbox Code Playgroud)
在单独的代码文件中:
defmodule Project.Logging do
#called just before Project.Logic.work_do_stuff with the same args
def before_work_do_stuff(arg) do
Log.write("about to work_do_stuff with #{inspect arg}")
end
# def after_work_do_stuff(some_result) implicitly defined as no-op,
# but could be overridden.
end
Run Code Online (Sandbox Code Playgroud)
最后,真正的问题是:启用这个魔法的代码是什么?
defmodule LoggingInjection do
defmacro inject(logging_module) do
#What goes here?
end
end
Run Code Online (Sandbox Code Playgroud) Feb 02, 2022 12:58:03 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@71318ec4: startup date [Wed Feb 02 12:58:03 IST 2022]; root of context hierarchy
Feb 02, 2022 12:58:03 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Feb 02, 2022 12:58:04 PM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; …Run Code Online (Sandbox Code Playgroud) 尝试对控制器包中的所有请求方法(所有 GET 和 POST)调用 around 建议。该建议不适用于请求方法。下面是我的控制器和方面建议方法。
此外,我需要打印请求映射参数,如方法类型(Get 或 Post)和请求的 URL。
控制器类:
package net.prc.sales.web.controller;
// imports
@SessionAttributes({Dictionary.FORM_DRIVER_INFO})
@Controller
public class CustomerInfoController {
@RequestMapping(value = Dictionary.URL_QUOTE_CUSTOMER_INFO, method = RequestMethod.GET)
public ModelAndView viewEsCustInfo(Model model, HttpSession session) throws SessionExpiredException {
ModelAndView mav = new ModelAndView();
// ...
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
方面建议:
@Around("net.prc.sales.web.controller.*.*(..) && " + "@annotation(RequestMapping)")
public void ourAroundAdvice(ProceedingJoinPoint method) {
System.out.println("Before-Advice Part:This is called before the method exceution.\n");
try {
method.proceed();
System.out.println("After-Returning-Advice Part: This is called after the method returns nomally.\n");
} …Run Code Online (Sandbox Code Playgroud) 我在 Spring Boot 中遇到了问题。我正在尝试为某些 RestControllers 提供额外的功能,并且我正在尝试使用一些自定义注释来实现它。这是一个例子。
我的注释:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String someArg();
}
Run Code Online (Sandbox Code Playgroud)
我的方面:
@Aspect
@Component
public class MyAspect {
@Around(
value = "@annotation(MyCustomAnnotation)",
argNames = "proceedingJoinPoint,someArg"
)
public Object addMyLogic(ProceedingJoinPoint proceedingJoinPoint, String someArg)
throws Throwable
{
System.out.println(someArg);
return proceedingJoinPoint.proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
我的方法:
@MyCustomAnnotation(someArg = "something")
@GetMapping("/whatever/route")
public SomeCustomResponse endpointAction(@RequestParam Long someId) {
SomeCustomResult result = someActionDoesNotMatter(someId);
return new SomeCustomResponse(result);
}
Run Code Online (Sandbox Code Playgroud)
主要基于文档(https://docs.spring.io/spring/docs/3.0.3.RELEASE/spring-framework-reference/html/aop.html - 7.2.4.6 Advice parameters)我很确定,它应该管用。
我在这里,因为它不...
让我发疯的是,即使是 Intellij,当试图帮助处理 argNames(空字符串 -> 红色下划线 -> alt+enter -> 正确的 …
春季手册说:
目标对象具有@Transactional批注的任何连接点(仅在Spring AOP中执行方法):@target(org.springframework.transaction.annotation .Transactional)
目标对象的声明类型具有@Transactional注释的任何连接点(仅在Spring AOP中是方法执行):@within(org.springframework.transaction.annotation .Transactional)
但是我看不出它们之间有什么区别!
我试图用谷歌搜索它:
两者之间的区别是@within()是静态匹配的,要求相应的注释类型仅具有CLASS保留。而@target()是在运行时匹配的,因此要求将其保留为RUNTIME。除此之外,在Spring上下文中,两个选择的连接点之间没有区别。
因此,我尝试添加具有CLASS保留的自定义注释,但是Spring抛出异常(因为注释必须具有 RUNTIME保留)
在执行类的静态方法之前和之后需要完成一些日志记录。我尝试使用 Spring AOP 来实现这一点,但它不起作用,而对于正常方法来说它起作用。请帮助我理解如何实现这一点,如果可以使用注释来完成,那就太好了。
我正在编写一个方面来记录控制器中每个 API 调用的请求和响应。我希望能够在类上使用此注释,因此使用 @Target(ElementType.TYPE)
之前我添加了 @Target(ElementType.Method) 并且我在方法上使用了这个注释并且它工作正常。现在我想将其更改为 @Target(ElementType.TYPE)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReLogger {}
Run Code Online (Sandbox Code Playgroud)
@Aspect
@Component
public class ReLoggerAspect {
public static final Logger log = LoggerFactory.getLogger("ReLoggerAspect");
@PostConstruct
private void postConstruct() {
log.info("ReLoggerAspect Created");
}
@Around("@annotation(ReLogger)")
private Object reqLoggingAspect(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("Request {}",jointPoint.getArgs()[0);
}
}
Run Code Online (Sandbox Code Playgroud)
在类上使用 @ReLoggerAspect
@RestController
@RequestMapping(value = "....", produces = { "application/json" })
@ReLogger
public class Samplecontroller {
/** Some logic here**/.....
}
Run Code Online (Sandbox Code Playgroud)
调用 API SampleController 时,它不会打印请求
我想使用AspectJ来监视数据库语句.
当我将切入点定义为
@Pointcut("execution(* java.sql.*Statement.execute*(..))")
Run Code Online (Sandbox Code Playgroud)
这是行不通的.但是当我将切入点定义为
@Pointcut("execution(* *.*(..))")
Run Code Online (Sandbox Code Playgroud)
它可以监控所有方法.
如何定义切入点以仅监视数据库访问方法?
我注意到在某些情况下,geb选择器无法按预期工作。当我从开发人员控制台复制css selecor,css路径或xpath并将其用作geb中的选择器时,它们将无法工作。无论如何,在此示例中,我无法选择我想要的:
网站:https://money.cnn.com/data/fear-and-greed/
<div id="needleChart" style="background-image:url('//money.cnn.com/.element/img/5.0/data/feargreed/1.png');">
<ul>
<li>Fear & Greed Now: 72 (Greed)</li><li>Fear & Greed Previous Close: 72 (Greed)</li>
<li>Fear & Greed 1 Week Ago: 69 (Greed)</li><li>Fear & Greed 1 Month Ago: 58 (Greed)</li>
<li>Fear & Greed 1 Year Ago: 8 (Extreme Fear)</li>
</ul>
</div>
Run Code Online (Sandbox Code Playgroud)
现在,我想从第一个li-tag 获取文本,这是我的代码:
public class MoneyCnnFearAndGreed extends Page {
static url = 'https://money.cnn.com/data/fear-and-greed'
static content = {
fearAndGreed { $("#needleChart").$("ul li")[0].text() }
}
}
Browser.drive {
to MoneyCnnFearAndGreed
println fearAndGreed
} …Run Code Online (Sandbox Code Playgroud) 当我使用maven-apsectj-plugin和maven-compiler-plugin compile阶段将执行两个插件compile目标。这会导致javac首先使用 进行编译,然后使用 进行完全重新编译ajc。
这个双重编译有必要吗?看来我可以关掉maven-compiler-plugin一切,一切正常。
我正在使用“默认”配置,如用法中所述maven-compiler-plugin:
<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<executions>
<execution>
<goals>
<goal>compile</goal> <!-- use this goal to weave all your main classes -->
<goal>test-compile</goal> <!-- use this goal to weave all your test classes -->
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
<build>
...
</project>
Run Code Online (Sandbox Code Playgroud) java ×7
aspectj ×5
spring-aop ×5
spring ×4
aop ×3
pointcut ×2
annotations ×1
cglib ×1
elixir ×1
erlang ×1
geb ×1
groovy ×1
jep-396 ×1
maven ×1
monitoring ×1
selenium ×1
spring-boot ×1
spring-mvc ×1
sql ×1
web-scraping ×1