是否可以使用spring和aspectj来进行编译时编织而不写入aspectj的.aj文件
如果有一个例子或教程那就太好了。
我正在研究 mysql 主从复制。我正在使用 spring data jpa(spring boot)。
我需要的是所有写入操作都转到主服务器,而只读操作则均匀分布在多个只读从服务器之间。
为此我需要:
使用特殊的 JDBC 驱动程序:com.mysql.jdbc.ReplicationDriver
在 URL 中设置复制:
spring:
datasource:
driverClassName: com.mysql.jdbc.ReplicationDriver
url: jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:3307/MyForum?user=root&password=password&autoReconnect=true
test-on-borrow: true
validation-query: SELECT 1
database: MYSQL
Run Code Online (Sandbox Code Playgroud)
需要关闭自动提交。(*) 连接需要设置为只读。
为了确保 JDBC Connection 设置为只读,我创建了一个注释和一个简单的 AOP 拦截器。
注解
package com.xyz.forum.replication;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Bhupati Patel on 02/11/15.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReadOnlyConnection {
}
Run Code Online (Sandbox Code Playgroud)
拦截器
package com.xyz.forum.replication;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; …Run Code Online (Sandbox Code Playgroud) 有没有办法在我有一个方面必须在其逻辑中使用一些复杂的实例化服务的情况下使用 Guice 和 AspectJ ?
例如:
@Aspect
public class SomeAspect {
private final ComplexServiceMangedByGuice complexServiceMangedByGuice;
@Inject
public SomeAspect(ComplexServiceMangedByGuice complexServiceMangedByGuice){
this.complexServiceMangedByGuice = complexServiceMangedByGuice;
}
@AfterThrowing(value = "execution(* *(..))", throwing = "e")
public void afterThrowingException(JoinPoint joinPoint, Throwable e){
complexServiceMangedByGuice.doSomething(e);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试像示例中那样(使用方面构造函数),我的方面将不会被调用。如果我尝试注入字段(没有定义方面构造函数),方面将被调用,但字段complexServiceMangedByGuice不会被设置。我发现的一个解决方案是在建议方法主体中获取实例,因此一个方面将如下所示:
@Aspect
public class SomeAspect {
private static ComplexServiceManagedByGuice complexServiceManagedByGuice;
@AfterThrowing(value = "execution(* *(..))", throwing = "e")
public void afterThrowingException(JoinPoint joinPoint, Throwable e){
if(complexServiceManagedByGuice == null){
Injector injector = Guice.createInjector(new ModuleWithComplexService());
complexServiceMangedByGuice = injector.getInstance(ComlexServiceManagedByGuice.class);
}
complexServiceMangedByGuice.doSomething(e);
}
}
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) 我正在尝试开始面向方面的编程。我正在使用最新的 eclipse(当前为 2019 年 12 月)
public aspect Observer {
}
Run Code Online (Sandbox Code Playgroud)
这会导致错误
Syntax error on token "aspect", interface expected
根据https://www.eclipse.org/ajdt/downloads
我添加了 http://download.eclipse.org/tools/ajdt/43/update
作为 eclipse 的更新站点
但是eclipse告诉我有些部分无法安装
看起来有些零件缺失了
无法完成安装,因为找不到一项或多项所需的项目。正在安装的软件:AspectJ 开发工具 2.2.3.e43x-RELEASE-20130627-0800 (org.eclipse.ajdt.feature.group 2.2.3.e43x-RELEASE-20130627-0800) 缺少要求:AspectJ 1.7.3.20130613144500-a ( org.aspectj.ajde 1.7.3.20130613144500-a) 需要 'osgi.bundle; org.eclipse.core.runtime.compatibility 0.0.0',但找不到无法满足依赖关系:来自:AspectJ Compiler 1.7.3.20130613144500-a(org.aspectj.feature.group 1.7.3.20130613144500-a)到:org. eclipse.equinox.p2.iu;org.aspectj.ajde [1.7.3.20130613144500-a,1.7.3.20130613144500-a] 无法满足依赖关系:来自:AspectJ 开发工具 2.2.3.e43x-RELEASE-20130627-0800 (org.eclipse.ajdt.feature.group 2.2. 3.e43x-RELEASE-20130627-0800) 至:org.eclipse.equinox.p2.iu;org.aspectj.feature.group [1.7.3.20130613144500-a,1.7.3.20130613144500-a]
如何让 Aspects 在 Eclipse 中运行?你能帮我一下吗?
我正在尝试更改 System.currentTimeMillis() 方法的行为以进行测试。我找到了下面的方法,但我不能在代码中使用 aspect 关键字。我真的不明白如何使用这种方法。有什么建议?
public aspect CurrentTimeInMillisMethodCallChanger {
long around():
call(public static native long java.lang.System.currentTimeMillis())
&& within(user.code.base.pckg.*) {
return 0; // provide your own implementation returning a long
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅包含上述代码来源的相关答案
我正在学习 AspectJ 注释,我认为 @After 注释在 @AfterThrowing 注释之前执行。但相反,它在它之后执行。为什么?
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Order(2)
public class MyDemoLoggingAspect {
@After("execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))")
public void afterFinallyFindAccountsAdvice(JoinPoint theJoinPoint) {
// print out which method we are advising on
String method = theJoinPoint.getSignature().toShortString();
System.out.println("\n=====>>> Executing @After (finally) on method: "
+ method);
}
@AfterThrowing(
pointcut="execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))",
throwing="theExc")
public void afterThrowingFindAccountsAdvice(
JoinPoint theJoinPoint, Throwable theExc) {
// print out which method we …Run Code Online (Sandbox Code Playgroud) 我的系统上安装了 pom 和 jdk 11 中的 aspectj-maven-plugin:1.11。Jdk 11 在 lib 目录中没有 tools.jar。这导致 maven 构建失败并出现错误:
[错误] 无法执行目标 org.codehaus.mojo:aspectj-maven-plugin:1.11:compile (default) on project groundtruth-storage-writer: 目标 org.codehaus.mojo 的执行默认:aspectj-maven-plugin:1.11 :compile failed: Plugin org.codehaus.mojo:aspectj-maven-plugin:1.11 或其依赖项之一无法解析:在指定路径找不到工件 com.sun:tools:jar:11.0.7 ...\ Java\jdk-11.0.7/../lib/tools.jar
如何解决这个问题?
有一个答案在这里,但超过2岁。
我想使用aspectj进行初始化.
@Aspect
public class TotoAspect
{
@Before("initialization( *.new(..))")
public void test(JoinPoint thisJoinPoint) throws AuditReactiveException
{
System.err.println("I AM HERE");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,消息没有打印出来
new ABC();
Run Code Online (Sandbox Code Playgroud)
我使用java代理进行aspectj.
哪里出错了?
/*我们使用Aspect在一些现有应用程序上执行AOP,我们还使用threadlocal来存储GUId.我们正在使用@Around注释.在事务开始时,我们使用initialValue()方法在事务中设置GUID.
问题就像我们所知,当我们使用threadlocal时,我们也应该注意从threadlocal中删除数据,否则它可能导致我的内存执行.如果我在最后一个方面删除它,它会破坏代码并更改UUID值.
请建议我们如何在没有outofmemory的情况下实现它.
代码: - */
@Aspect
public class DemoAspect {
@Pointcut("execution(* *.*(..)) ")
public void logging() {}
private static ThreadLocal<String> id = new ThreadLocal<String>() {
@Override
protected String initialValue(){
return UUID.randomUUID().toString();
}
};
@Around("logging()")
public Object tracing(ProceedingJoinPoint thisJoinPoint) throws Throwable {
String methodSignature=thisJoinPoint.getSignature().toString();
if(id.get().toString()==null || id.get().toString().length()==0)
id.set(UUID.randomUUID().toString());
System.out.println("Entering into "+methodSignature);
Object ret = thisJoinPoint.proceed();
System.out.println(id.get().toString());
System.out.println("Exiting into "+methodSignature);
//id.remove();
return ret;
}
}
Run Code Online (Sandbox Code Playgroud) 我是aspectj的新手,我怀疑是否可以使用aspectj在jar文件中存在的函数之前注入代码.
aspectj ×11
java ×9
aop ×2
spring ×2
spring-aop ×2
aspect ×1
eclipse ×1
guice ×1
java-11 ×1
maven ×1
maven-plugin ×1
thread-local ×1