任何连接点(仅在Spring AOP中执行方法),其中目标对象具有@transactional注释:@target(org.springframework.transaction.annotation.transactional)
任何连接点(仅在Spring AOP中执行方法),其中目标对象的声明类型具有@transactional注释:@inne(org.springframework.transaction.annotation.transactional)
但我看不出他们有什么不同!
所以我尝试添加带有类保留的自定义注释,但Spring抛出了一个异常(因为注释必须具有运行时保留)
您没有注意到任何区别,因为Spring AOP在使用AspectJ语法的同时,实际上只模拟了其功能的一个有限子集。因为Spring AOP是基于动态代理的,所以它只提供对公共的、非静态方法执行的拦截。(在使用CGLIB代理时,还可以截获包范围内的和受保护的方法。)然而,AspectJ还可以拦截方法调用(不仅仅是执行)、成员字段访问(静态和非静态)、构造函数调用/执行、静态类初始化等。
因此,让我们构造一个非常简单的AspectJ示例:
标记注释:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
package de.scrum_master.app;
@MyAnnotation
public class Application {
private int nonStaticMember;
private static int staticMember;
public void doSomething() {
System.out.println("Doing something");
nonStaticMember = 11;
}
public void doSomethingElse() {
System.out.println("Doing something else");
staticMember = 22;
}
public static void main(String[] args) {
Application application = new Application();
application.doSomething();
application.doSomethingElse();
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("@within(de.scrum_master.app.MyAnnotation) && execution(public !static * *(..))")
public void adviceAtWithin(JoinPoint thisJoinPoint) {
System.out.println("[@within] " + thisJoinPoint);
}
@Before("@target(de.scrum_master.app.MyAnnotation) && execution(public !static * *(..))")
public void adviceAtTarget(JoinPoint thisJoinPoint) {
System.out.println("[@target] " + thisJoinPoint);
}
}
[@within] execution(void de.scrum_master.app.Application.doSomething())
[@target] execution(void de.scrum_master.app.Application.doSomething())
Doing something
[@within] execution(void de.scrum_master.app.Application.doSomethingElse())
[@target] execution(void de.scrum_master.app.Application.doSomethingElse())
Doing something else
[@within] staticinitialization(de.scrum_master.app.Application.<clinit>)
[@within] execution(void de.scrum_master.app.Application.main(String[]))
[@within] call(de.scrum_master.app.Application())
[@within] preinitialization(de.scrum_master.app.Application())
[@within] initialization(de.scrum_master.app.Application())
[@target] initialization(de.scrum_master.app.Application())
[@within] execution(de.scrum_master.app.Application())
[@target] execution(de.scrum_master.app.Application())
[@within] call(void de.scrum_master.app.Application.doSomething())
[@target] call(void de.scrum_master.app.Application.doSomething())
[@within] execution(void de.scrum_master.app.Application.doSomething())
[@target] execution(void de.scrum_master.app.Application.doSomething())
[@within] get(PrintStream java.lang.System.out)
[@within] call(void java.io.PrintStream.println(String))
Doing something
[@within] set(int de.scrum_master.app.Application.nonStaticMember)
[@target] set(int de.scrum_master.app.Application.nonStaticMember)
[@within] call(void de.scrum_master.app.Application.doSomethingElse())
[@target] call(void de.scrum_master.app.Application.doSomethingElse())
[@within] execution(void de.scrum_master.app.Application.doSomethingElse())
[@target] execution(void de.scrum_master.app.Application.doSomethingElse())
[@within] get(PrintStream java.lang.System.out)
[@within] call(void java.io.PrintStream.println(String))
Doing something else
[@within] set(int de.scrum_master.app.Application.staticMember)
当只查看@target()
时,我们会看到:
[@target] initialization(de.scrum_master.app.Application())
[@target] execution(de.scrum_master.app.Application())
[@target] call(void de.scrum_master.app.Application.doSomething())
[@target] execution(void de.scrum_master.app.Application.doSomething())
Doing something
[@target] set(int de.scrum_master.app.Application.nonStaticMember)
[@target] call(void de.scrum_master.app.Application.doSomethingElse())
[@target] execution(void de.scrum_master.app.Application.doSomethingElse())
Doing something else
对于每个方面输出行,我们还可以看到一个对应的@intern()
匹配。现在让我们集中讨论哪些是不相同的,过滤输出的差异:
[@within] staticinitialization(de.scrum_master.app.Application.<clinit>)
[@within] execution(void de.scrum_master.app.Application.main(String[]))
[@within] call(de.scrum_master.app.Application())
[@within] preinitialization(de.scrum_master.app.Application())
[@within] get(PrintStream java.lang.System.out)
[@within] call(void java.io.PrintStream.println(String))
Doing something
[@within] get(PrintStream java.lang.System.out)
[@within] call(void java.io.PrintStream.println(String))
Doing something else
[@within] set(int de.scrum_master.app.Application.staticMember)
你看,在外表上
问题内容: 这两个连接将给我相同的结果: 与 语句之间的性能或其他方面有什么区别吗? 不同的 SQL 实现之间是否有所不同? 问题答案: 它们在功能上是等效的,但阅读起来可能更清晰,尤其是在查询中包含其他联接类型(即or或)的情况下。
本文向大家介绍inner join和left join之间的区别详解,包括了inner join和left join之间的区别详解的使用技巧和注意事项,需要的朋友参考一下 前言 关于inner join 与 left join 之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在inner join 上了。 需求是从数据库查数据,在前端以柱形图的形式展现出来,
问题内容: 使用Java编译器()时,我们可以指定两种兼容性。一个正在使用,另一个正在使用。两者有什么区别? 例如和? 另外,在任何情况下我们使用不同的源和目标兼容性级别吗? 问题答案: 从javac文档: -source 指定接受的源代码版本。 -target 生成针对指定版本的VM的类文件。类文件将在指定的目标和更高版本上运行,但不会在VM的早期版本上运行。 在您的示例中: 这将用于确保源代码
问题内容: 我错放了太多次了,我想我一直忘记,因为我不知道两者之间的区别,只是一个给了我我期望的价值,而另一个却没有。 为什么是这样? 问题答案: 是的简写形式(尽管请注意,该表达式只会被计算一次。) 是的,即指定一元的到。 例子:
问题内容: 因此,我有一段简单的代码可以打印出整数1-10: 然后,如果仅在第3行上更改一个运算符,它将打印出无限数量的1整数(我知道为什么会这样做)。为什么在运行第二个程序时没有出现语法错误?如果赋值运算符后面跟着一个加法运算符,它不会调用语法错误吗? 问题答案: 与相同, 只是意味着。