├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .travis.yml
├── README.adoc
├── benchmarks
├── README.adoc
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ ├── aspects
│ │ │ ├── ServiceInterceptor1.java
│ │ │ ├── ServiceInterceptor10.java
│ │ │ ├── ServiceInterceptor11.java
│ │ │ ├── ServiceInterceptor12.java
│ │ │ ├── ServiceInterceptor13.java
│ │ │ ├── ServiceInterceptor14.java
│ │ │ ├── ServiceInterceptor15.java
│ │ │ ├── ServiceInterceptor16.java
│ │ │ ├── ServiceInterceptor17.java
│ │ │ ├── ServiceInterceptor18.java
│ │ │ ├── ServiceInterceptor19.java
│ │ │ ├── ServiceInterceptor2.java
│ │ │ ├── ServiceInterceptor20.java
│ │ │ ├── ServiceInterceptor3.java
│ │ │ ├── ServiceInterceptor4.java
│ │ │ ├── ServiceInterceptor5.java
│ │ │ ├── ServiceInterceptor6.java
│ │ │ ├── ServiceInterceptor7.java
│ │ │ ├── ServiceInterceptor8.java
│ │ │ └── ServiceInterceptor9.java
│ │ │ └── example
│ │ │ ├── Interceptor.java
│ │ │ ├── InterceptorApplication.java
│ │ │ └── MultiBeanConfiguration.java
│ └── resources
│ │ ├── application.properties
│ │ └── org
│ │ └── aspectj
│ │ └── aop.xml
│ └── test
│ └── java
│ └── com
│ ├── bench
│ ├── ProcessLauncherState.java
│ ├── ProcessLauncherStateTest.java
│ └── StartupBenchmark.java
│ └── example
│ └── InterceptorApplicationTests.java
├── ctw
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ ├── Interceptor.java
│ │ │ └── InterceptorApplication.java
│ └── resources
│ │ ├── application.properties
│ │ └── org
│ │ └── aspectj
│ │ └── aop.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── InterceptorApplicationTests.java
├── ltw
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ ├── Interceptor.java
│ │ │ └── InterceptorApplication.java
│ └── resources
│ │ ├── application.properties
│ │ └── org
│ │ └── aspectj
│ │ └── aop.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── InterceptorApplicationTests.java
├── multi-ctw
├── ctw-app
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── InterceptorApplication.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── org
│ │ │ └── aspectj
│ │ │ └── aop.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── InterceptorApplicationTests.java
├── ctw-aspects
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── Interceptor.java
└── pom.xml
├── multi-ltw
├── ltw-app
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── InterceptorApplication.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── org
│ │ │ └── aspectj
│ │ │ └── aop.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── InterceptorApplicationTests.java
├── ltw-aspects
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── Interceptor.java
└── pom.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── spring
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ ├── Interceptor.java
│ │ │ └── InterceptorApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── InterceptorApplicationTests.java
└── timing
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── springframework
│ │ └── boot
│ │ └── aspects
│ │ ├── AspectConfiguration.java
│ │ └── TimingInterceptor.java
└── resources
│ └── META-INF
│ ├── aop.xml
│ └── spring.factories
└── test
└── java
└── org
└── springframework
└── boot
└── aspects
├── DemoApplication.java
└── DemoApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | dependency-reduced-pom.xml
4 | interpolated-pom.xml
5 | .#*
6 | *#
7 | *~
8 | build.log
9 | _site/
10 | .vscode/
11 |
12 | ### STS ###
13 | .apt_generated
14 | .classpath
15 | .factorypath
16 | .project
17 | .settings
18 | .springBeans
19 | *.DS_Store*
20 |
21 | ### IntelliJ IDEA ###
22 | .idea
23 | *.iws
24 | *.iml
25 | *.ipr
26 |
27 | ### NetBeans ###
28 | nbproject/private/
29 | build/
30 | nbbuild/
31 | dist/
32 | nbdist/
33 | .nb-gradle/
34 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dsyer/spring-boot-aspectj/79f5f76a398657bd846045b33621375f43c24aef/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | script: mvn clean install
3 |
4 | cache:
5 | directories:
6 | - $HOME/.m2/repository
7 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | == Sample Apps Showing How to Use AspectJ Natively with `@Aspect` and Spring Boot
2 |
3 | image:https://travis-ci.com/lofidewanto/spring-boot-aspectj.svg?branch=master["Build Status", link="https://travis-ci.com/lofidewanto/spring-boot-aspectj"]
4 |
5 | AspectJ lets you write aspects using Java annotations `@Aspect` and friends. Conveniently, but sometimes confusingly, Spring lets you use the same programming model, and then uses the AspectJ tooling APIs at runtime, so some people can't tell the difference between Spring AOP and AspectJ. You don't need any special tools to use Spring AOP, but it has it's limitations, one of which is performance (you take a hit on startup while all the beans are analysed, and you take another smaller hit when the app is running and one of your aspects is executed through a proxy).
6 |
7 | Luckily, it is quite easy to set up AspectJ to weave your code natively (not with Spring), and it is sometimes faster - just more steps to set up. In fact, there are multiple ways of using AspectJ to weave your code, some of which happen at runtime, and one (broadly speaking) that happens at compile time. Compile time is faster (unsurprisingly), but not massively (heuristically, maybe a 20% effect).
8 |
9 | NOTE: The projects are updated with AspectJ 1.9.5 (included with Spring Boot 2.2.4) and use OpenJDK 11 now.
10 |
11 | NOTE: AspectJ 1.8.13 (included with Spring Boot 1.5.9) has some major performance improvements affecting Spring AOP - the optimizations were suggested by running the benchmarks in this project. If you think Spring AOP might be slowing your app down on startup, upgrade now.
12 |
13 | == Contents
14 |
15 | * spring = Spring AOP standalone sample. Aspects and application code in the same module.
16 | * ltw = Load Time Weaving standalone sample. Aspects and application code in the same module.
17 | * ctw = Compile Time Weaving standalone sample. Aspects and application code in the same module.
18 | * multi-ltw = Load Time Weaving multi-module sample. Aspects and application code in separate modules.
19 | * multi-ctw = Compile Time Weaving multi-module sample. Aspects and application code in separate modules. The aspect library (as well as the application) has to be processed by AspectJ at build time.
20 | * timing = A utility library for logging timing data on startup for some internal features of Spring and Spring Boot
21 | * benchmarks = benchmarks for using AspectJ with the help of https://www.baeldung.com/java-microbenchmark-harness[JMH (Java Microbenchmark Harness)] for example of how to do microbenchmarking in Java. Also this article about http://tutorials.jenkov.com/java-performance/jmh.html[JMH] is a good place to start.
22 |
23 | == Converting from Spring AOP to AspectJ
24 |
25 | You need to tell AspectJ where to find your aspects, and which classes you want it to weave. You also need to tell Spring not to try and weave the same aspects again (in Spring Boot you can do that with `spring.aop.auto=false`). The configuration for AspectJ lives in an https://eclipse.org/aspectj/doc/next/devguide/ltw-configuration.html[XML file] `aop.xml`, which can be in `META-INF` or in a package called `org.aspectj`. Here's a simple example:
26 |
27 | .src/main/resources/org/aspectj/aop.xml
28 | [source,xml]
29 | ----
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ----
43 |
44 | WARNING: If the AspectJ config file is in `META-INF/aop.xml` then the fat jar built by Spring Boot has it is in the wrong place, and there are nasty looking https://github.com/spring-projects/spring-boot/issues/7587[errors on startup]. The app still works and the aspects are woven, but you can work around it by putting `aop.xml` in the `org.aspectj` package instead of in `META-INF`.
45 |
46 | == Load Time Weaving
47 |
48 | One of the runtime options is called "load time weaving", and Spring even has an annotation `@EnableLoadTimeWeaving` to help get it off the ground. The Spring annotation is rooted in the culture and mechanics of application servers - it only makes sense if you have multiple apps running in the same JVM with class loader isolation. What happens is that it uses a special `ClassLoader` that manipulates the classes as they are loaded.
49 |
50 | The other option for load time weaving is the AspectJ agent, which you add to the JVM on the command line, and it can look at all the classes and potentially weave them with aspects.
51 |
52 | E.g. :
53 |
54 | ```
55 | $ cd ltw
56 | $ mvn clean install
57 | $ java -javaagent:$HOME/.m2/repository/org/aspectj/aspectjweaver/[version]/aspectjweaver-[version].jar -jar target/*.jar
58 | ```
59 |
60 | You can also use the copied version of aspectweaver-[version].jar in the target/aspectj directory of the Maven project, since it is copied to that directory with Maven Dependency plugin.
61 |
62 | ```
63 | $ java -javaagent:target/aspectj/aspectjweaver-[version].jar -jar target/*.jar
64 | ```
65 |
66 | If you don't add the agent (and don't provide an implementation of `Interceptor.aspectOf()`) you might get a confusing "cyclic dependency" error from Spring on startup. It's not really cyclic, but because the `Interceptor` in this sample is an `@EventListener` Spring is trying to create it very early and gets confused. The real problem is just that `Aspects.aspectOf()` doesn't work unless the agent is attached.
67 |
68 | NOTE: `@EnableLoadTimeWeaving` doesn't actually make much sense in a Spring Boot app that is going to run in its own process - you can just add the AspectJ agent. Many people confuse "load time weaving" with "runtime weaving" generally (because for a long time it was the only option for many Spring apps). So if someone asks you to implement "load time weaving" in a Spring Boot app, just add the agent.
69 |
70 | NOTE: The "timing" library is a dependency of this project so it gets woven at runtime and prints out interesting (but verbose) information about timings for bean initialization. This is in addition to the aspects library.
71 |
72 | == Compile Time Weaving
73 |
74 | To weave the aspects at compile time (and also optionally use the AspectJ language, as opposed to Java with annotations), you need an additional plugin in your build. If all you need is to weave existing byte code, the plugin configuration is very simple:
75 |
76 | [source,xml]
77 | ----
78 |
79 | org.codehaus.mojo <3>
80 | aspectj-maven-plugin
81 | 1.10
82 |
83 | ${java.version}
84 | ${java.version}
85 | none <1>
86 | ${java.version}
87 |
88 |
89 |
90 |
91 | compile
92 |
93 |
94 |
95 |
96 |
97 | org.aspectj
98 | aspectjtools
99 | ${aspectj.version} <2>
100 |
101 |
102 |
103 | ----
104 | <1> Useful if you have annotation processors (like Spring Boot configuration processor), to avoid them being processed again by the AspectJ compiler.
105 | <2> Optionally update the AspectJ tooling to the latest version. The `aspectrt` jar has to be included separately.
106 | <3> See the note below for Java 11
107 |
108 | In this sample build the app with the `weave` profile to run this plugin. E.g.
109 |
110 | ```
111 | $ cd ctw
112 | $ mvn clean install
113 | $ java -jar target/*.jar
114 | ```
115 |
116 | NOTE: for Java 11 you cannot use org.codehaus.mojo::aspectj-maven-plugin because the plugin is not developed anymore, see https://github.com/mojohaus/aspectj-maven-plugin/issues/49. Instead use https://github.com/nickwongdev/aspectj-maven-plugin with com.nickwongdev::aspectj-maven-plugin
117 |
118 | NOTE: in the plugin configuration above, we haven't asked AspectJ to weave the dependencies, and it won't do that by default. Consequently we won't see as much output from the app when it runs as we did with the runtime weaving (where all the classes were available for weaving as soon as they were loaded).
119 |
120 | NOTE: AspectJ is smart enough not to try and weave the same class twice, so you can always add the agent at runtime even when the application classes are already woven. That would be one way to pick up additional join points that you hadn't woven at compile time.
121 |
122 | NOTE: The "timing" library is not a dependency of this project, and there wouldn't be much point doing that because the pointcuts it defines would not match anything that was being compiled here.
123 |
124 | == Running the LTW Sample
125 |
126 | You can run the samples from the command line and see the aspect logging to stderr:
127 |
128 | ```
129 | $ cd ltw
130 | $ mvn spring-boot:run
131 | ...
132 | execution(InterceptorApplication..EnhancerBySpringCGLIB..8ce66f62.setBeanFactory(..))
133 | execution(InterceptorApplication..EnhancerBySpringCGLIB..8ce66f62.setBeanFactory(..))
134 | ...
135 | ```
136 |
137 | To run in the IDE you need to add the agent to your launch configuration.
138 |
139 | ```
140 | -javaagent:${system_property:user.home}/.m2/repository/org/aspectj/aspectjweaver/[version]/aspectjweaver-[version].jar
141 | ```
142 |
143 | or simply
144 |
145 | ```
146 | -javaagent:target/aspectj/aspectjweaver-[version].jar
147 | ```
148 |
149 | Note that you could add `@EnableLoadTimeWeaving` to the main application class, but it should probably be removed, as it's misleading.
150 |
151 | There's an open issue asking for `@EnableLoadTimeWeaving` support in Spring Boot, and a user who says he made it work with a `PropertiesLauncher` (because it can set the class loader really early): https://github.com/spring-projects/spring-boot/issues/739. It doesn't work to set the classloader in the main method because too many Spring Boot classes have already been loaded by then, but there is a trick you can play with [attaching the agent at runtime](http://www.eclipse.org/aspectj/doc/released/README-187.html) (in which case all classes loaded up to that point can not be woven).
152 |
153 | NOTE: You can enable logging of the weaving using `-Daj.weaving.verbose=true`.
154 |
155 | == Run the CTW Sample
156 |
157 | ```
158 | $ cd ctw
159 | $ mvn spring-boot:run
160 | ```
161 |
162 | The compile time weaving example does not need any Java agent.
163 |
164 | == Useful Links
165 |
166 | * https://stackoverflow.com/questions/21350966/using-autowired-with-aspectj-and-springboot/21367986
167 | * https://stackoverflow.com/questions/12423965/maven-aspectj-all-steps-to-configure-it
168 | * https://stackoverflow.com/questions/40472614/simple-configurable-with-modern-spring-boot-gradle
169 | * https://www.eclipse.org/aspectj/doc/released/README-187.html
170 | * https://github.com/spring-projects/spring-boot/issues/6626
171 | * https://github.com/spring-projects/spring-boot/issues/7587
172 | * https://github.com/spring-projects/spring-boot/issues/739
173 |
--------------------------------------------------------------------------------
/benchmarks/README.adoc:
--------------------------------------------------------------------------------
1 | = Benchmarks
2 |
3 | == How to run
4 |
5 | The Surefire Maven Plugin will run the benchmarking process:
6 |
7 | ```
8 | $ cd benchmarks
9 | $ mvn test -Dtest=StartupBenchmark
10 | ```
11 |
12 | Outside Maven after building the benchmarks.jar you can just run the `StartupBenchmark` in your IDE.
13 |
14 | = Results
15 |
16 | === JDK 11
17 |
18 | ```
19 | class method scale median mean range
20 | com.bench.StartupBenchmark ltw 2.398 2.473 0.113
21 | com.bench.StartupBenchmark ltw_100 2.404 2.431 0.037
22 | com.bench.StartupBenchmark spring v0_10 1.604 1.648 0.039
23 | com.bench.StartupBenchmark spring v1_10 1.714 1.748 0.030
24 | com.bench.StartupBenchmark spring v1_100 1.767 1.792 0.019
25 | com.bench.StartupBenchmark spring v10_50 2.204 2.284 0.062
26 | com.bench.StartupBenchmark spring v20_50 2.801 2.828 0.033
27 | com.bench.StartupBenchmark spring a0_10 1.621 1.659 0.042
28 | com.bench.StartupBenchmark spring a1_10 1.704 1.772 0.139
29 | com.bench.StartupBenchmark spring a1_100 1.700 1.774 0.157
30 | com.bench.StartupBenchmark spring a10_50 2.004 2.104 0.146
31 | com.bench.StartupBenchmark spring a10_100 1.943 1.988 0.084
32 | com.bench.StartupBenchmark spring a20_50 2.216 2.268 0.056
33 | ```
34 |
35 | === JDK 8
36 |
37 | ```
38 | class method scale median mean range
39 | com.bench.StartupBenchmark ltw 2.020 2.044 0.063
40 | com.bench.StartupBenchmark ltw_100 2.050 2.078 0.042
41 | com.bench.StartupBenchmark spring v0_10 1.532 1.550 0.018
42 | com.bench.StartupBenchmark spring v1_10 1.621 1.662 0.051
43 | com.bench.StartupBenchmark spring v1_100 1.653 1.669 0.026
44 | com.bench.StartupBenchmark spring v10_50 2.120 2.148 0.036
45 | com.bench.StartupBenchmark spring v20_50 2.657 2.692 0.034
46 | com.bench.StartupBenchmark spring a0_10 1.517 1.537 0.025
47 | com.bench.StartupBenchmark spring a1_10 1.624 1.638 0.019
48 | com.bench.StartupBenchmark spring a1_100 1.651 1.670 0.015
49 | com.bench.StartupBenchmark spring a10_50 1.905 1.927 0.020
50 | com.bench.StartupBenchmark spring a10_100 1.900 1.931 0.035
51 | com.bench.StartupBenchmark spring a20_50 2.124 2.162 0.052
52 | ```
53 |
54 | == Older Results
55 |
56 | === AspectJ 1.8.11 Snapshots
57 |
58 | (Seems to fix the problem with Spring AOP.)
59 |
60 | ```
61 | Benchmark (scale) Mode Cnt Score Error Units
62 | StartupBenchmark.ltw N/A avgt 10 1.878 ± 0.039 s/op
63 | StartupBenchmark.ltw_100 N/A avgt 10 1.930 ± 0.083 s/op
64 | StartupBenchmark.spring v0_10 avgt 10 1.485 ± 0.033 s/op
65 | StartupBenchmark.spring v1_10 avgt 10 1.605 ± 0.069 s/op
66 | StartupBenchmark.spring v1_100 avgt 10 1.629 ± 0.022 s/op
67 | StartupBenchmark.spring v10_50 avgt 10 2.176 ± 0.091 s/op
68 | StartupBenchmark.spring v20_50 avgt 10 2.771 ± 0.080 s/op
69 | StartupBenchmark.spring a0_10 avgt 10 1.485 ± 0.049 s/op
70 | StartupBenchmark.spring a1_10 avgt 10 1.564 ± 0.032 s/op
71 | StartupBenchmark.spring a1_100 avgt 10 1.603 ± 0.047 s/op
72 | StartupBenchmark.spring a10_50 avgt 10 1.831 ± 0.013 s/op
73 | StartupBenchmark.spring a10_100 avgt 10 1.890 ± 0.060 s/op
74 | StartupBenchmark.spring a20_50 avgt 10 2.121 ± 0.083 s/op
75 | ```
76 |
77 | === AspectJ 1.8.10
78 |
79 | ```
80 | Benchmark Mode Cnt Score Error Units
81 | StartupBenchmark.null avgt 10 2.114 ± 0.134 s/op
82 | StartupBenchmark.ltw avgt 10 2.749 ± 0.067 s/op
83 | StartupBenchmark.ltw_10 avgt 10 2.914 ± 0.110 s/op
84 | StartupBenchmark.ltw_10_100 avgt 10 2.873 ± 0.114 s/op
85 | StartupBenchmark.ltw_20 avgt 10 2.900 ± 0.110 s/op
86 | StartupBenchmark.ltw_20_100 avgt 10 2.965 ± 0.114 s/op
87 | StartupBenchmark.annotation avgt 10 2.113 ± 0.095 s/op
88 | StartupBenchmark.annotation_10_100 avgt 10 7.204 ± 0.062 s/op
89 | StartupBenchmark.annotation_10_50 avgt 10 7.199 ± 0.092 s/op
90 | StartupBenchmark.annotation_1_100 avgt 10 2.838 ± 0.115 s/op
91 | StartupBenchmark.annotation_1_50 avgt 10 2.814 ± 0.070 s/op
92 | StartupBenchmark.annotation_20_100 avgt 10 11.512 ± 0.106 s/op
93 | StartupBenchmark.annotation_20_50 avgt 10 11.476 ± 0.132 s/op
94 | ```
95 |
96 | .Number of @Aspects vs. Startup Time
97 | image::https://docs.google.com/spreadsheets/d/e/2PACX-1vR8B4l5WkWf-9gZWmIYTkmBWM7YWf5bRg852OakrV0G2-vtfM_UkVNRC3cTVk1079HagnMVHYZnvbib/pubchart?oid=756916910&format=image[]
98 |
99 | Legend:
100 |
101 | * null: No aspect weaving at all.
102 | * annotation: Spring AOP. No aspects with method annotation pointcuts.
103 | * annotation_1_50: Spring AOP with extra aspects(1) and beans(50).
104 | * annotation_1_100: Spring AOP with extra aspects(1) and beans(100).
105 | * annotation_10_50: Spring AOP with extra aspects(10) and beans(50).
106 | * annotation_10_50: Spring AOP with extra aspects(10) and beans(100).
107 | * annotation_20_50: Spring AOP with extra aspects(20) and beans(50).
108 | * annotation_20_50: Spring AOP with extra aspects(20) and beans(100).
109 | * ltw: Load Time Weaving. Aspects woven by AspectJ agent, not Spring.
110 | * ltw_10: Load Time Weaving with extra aspects (10).
111 | * ltw_10_100: Load Time Weaving with extra aspects(10) and beans(100).
112 | * ltw_20: Load Time Weaving with extra aspects (20).
113 | * ltw_20_100: Load Time Weaving with extra aspects(20) and beans(100).
114 |
115 | |===
116 | | sample | @aspects | beans | startup(millis)
117 |
118 | | null | 0 | 188 | 2117
119 | | ltw | 0 | 188 | 2749
120 | | ltw_10 | 10| 188 | 2914
121 | | ltw_10_100 | 10| 288 | 2873
122 | | ltw_20 | 20| 188 | 2900
123 | | ltw_20_100 | 20| 288 | 2965
124 | | annotation | 0 | 191 | 2113
125 | | annotation_1_50 | 1 | 242 | 2814
126 | | annotation_1_100 | 1 | 292 | 2838
127 | | annotation_10_50 | 10| 251 | 7119
128 | | annotation_10_100 | 10| 301 | 7204
129 | | annotation_20_50 | 20| 261 | 11476
130 | | annotation_20_100 | 20| 311 | 11512
131 |
132 |
133 | |===
134 |
135 | The annotation (Spring AOP) samples are much slower with @aspects than
136 | without and the slow down is proportional to the number of pointcuts
137 | (not so much with the number of beans). It's pretty awful: 400ms per
138 | pointcut.
139 |
140 | The "ltw" samples are a bit slower with @aspects than without, but the
141 | slow down is not proportional to the number of pointcuts. Note,
142 | however, that all the pointcuts were the same, so maybe there is some
143 | optimization in AspectJ that doesn't help for a realistic system.
144 |
--------------------------------------------------------------------------------
/benchmarks/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.example
8 | benchmarks
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | benchmarks
13 | Demo project for Spring Boot
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.2.4.RELEASE
19 |
20 |
21 |
22 |
23 | UTF-8
24 | UTF-8
25 | 8
26 | 1.23
27 | 1.0.24.RELEASE
28 | org.openjdk.jmh.Main
29 |
30 |
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-actuator
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-aop
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-web
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-configuration-processor
47 | true
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-test
53 | test
54 |
55 |
56 |
57 | org.openjdk.jmh
58 | jmh-core
59 | ${jmh.version}
60 |
61 |
62 |
63 | org.openjdk.jmh
64 | jmh-generator-annprocess
65 | ${jmh.version}
66 | provided
67 |
68 |
69 |
70 | com.github.mp911de.microbenchmark-runner
71 | microbenchmark-runner-junit5
72 | 0.2.0.RELEASE
73 | test
74 |
75 |
76 | com.github.mp911de.microbenchmark-runner
77 | microbenchmark-runner-extras
78 | 0.2.0.RELEASE
79 | test
80 |
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-starter-test
85 | test
86 |
87 |
88 | junit
89 | junit
90 |
91 |
92 | org.junit.vintage
93 | junit-vintage-engine
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | tools.jar
103 |
104 | [1.8,1.9)
105 |
106 |
107 |
108 | com.sun
109 | tools
110 | 1.8
111 | system
112 | ${java.home}/../lib/tools.jar
113 |
114 |
115 |
116 |
117 |
118 |
119 | benchmarks
120 |
121 |
122 | org.apache.maven.plugins
123 | maven-compiler-plugin
124 |
125 |
126 |
127 | org.openjdk.jmh
128 | jmh-generator-annprocess
129 | ${jmh.version}
130 |
131 |
132 | ${java.version}
133 | ${java.version}
134 |
135 |
136 |
137 |
138 | maven-deploy-plugin
139 |
140 | true
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | jitpack.io
149 | https://jitpack.io
150 |
151 |
152 | spring-snapshots
153 | Spring Snapshots
154 | https://repo.spring.io/snapshot
155 |
156 | true
157 |
158 |
159 |
160 | spring-milestones
161 | Spring Milestones
162 | https://repo.spring.io/milestone
163 |
164 | false
165 |
166 |
167 |
168 |
169 |
170 | spring-snapshots
171 | Spring Snapshots
172 | https://repo.spring.io/snapshot
173 |
174 | true
175 |
176 |
177 |
178 | spring-milestones
179 | Spring Milestones
180 | https://repo.spring.io/milestone
181 |
182 | false
183 |
184 |
185 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor1.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor1 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor10.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor10 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor11.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor11 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor12.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor12 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor13.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor13 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor14.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor14 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor15.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor15 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor16.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor16 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor17.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor17 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor18.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor18 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor19.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor19 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor2.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor2 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor20.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor20 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor3.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor3 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor4.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor4 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor5.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor5 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor6.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | * Copyright 2016-2017 the original author or authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.aspects;
19 |
20 | import org.aspectj.lang.ProceedingJoinPoint;
21 | import org.aspectj.lang.annotation.Around;
22 | import org.aspectj.lang.annotation.Aspect;
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | @Aspect
29 | class ServiceInterceptor6 {
30 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor7.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor7 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor8.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor8 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/aspects/ServiceInterceptor9.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.aspects;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | @Aspect
28 | class ServiceInterceptor9 {
29 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* *.*(..))")
30 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
31 | Object result = joinPoint.proceed();
32 | System.err.println(joinPoint.toShortString() + ": " + result);
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 |
7 | import org.springframework.boot.context.properties.ConfigurationProperties;
8 | import org.springframework.context.event.ContextRefreshedEvent;
9 | import org.springframework.context.event.EventListener;
10 | import org.springframework.stereotype.Component;
11 |
12 | @Aspect
13 | @ConfigurationProperties("interceptor")
14 | @Component
15 | public class Interceptor {
16 |
17 | /**
18 | * Message to print on startup
19 | */
20 | private String message = "Up";
21 |
22 | public String getMessage() {
23 | return message;
24 | }
25 |
26 | public void setMessage(String message) {
27 | this.message = message;
28 | }
29 |
30 | @Around("execution(* *.*(..)) && within(com.example..*)")
31 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
32 | Object result = joinPoint.proceed();
33 | System.err.println(joinPoint.toShortString() + ": " + result);
34 | return result;
35 | }
36 |
37 | @EventListener
38 | public void started(ContextRefreshedEvent event) {
39 | System.err.println(message + ": " + event);
40 | System.err.println("Beans: " + event.getApplicationContext().getBeanDefinitionCount());
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @SpringBootApplication
9 | @RestController
10 | public class InterceptorApplication {
11 |
12 | @RequestMapping("/")
13 | public String home() {
14 | return "Hello World";
15 | }
16 |
17 | public static void main(String[] args) {
18 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/benchmarks/src/main/java/com/example/MultiBeanConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example;
18 |
19 | import org.aspectj.lang.ProceedingJoinPoint;
20 | import org.aspectj.lang.annotation.Around;
21 | import org.aspectj.lang.annotation.Aspect;
22 |
23 | import org.springframework.beans.factory.support.BeanDefinitionBuilder;
24 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
25 | import org.springframework.beans.factory.support.DefaultListableBeanFactory;
26 | import org.springframework.context.annotation.Configuration;
27 | import org.springframework.context.annotation.Import;
28 | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
29 | import org.springframework.core.env.ConfigurableEnvironment;
30 | import org.springframework.core.type.AnnotationMetadata;
31 |
32 | /**
33 | * @author Dave Syer
34 | *
35 | */
36 | @Configuration
37 | @Import(MultiBeanSelector.class)
38 | public class MultiBeanConfiguration {
39 | }
40 |
41 | class Service {
42 | public void execute() {
43 | }
44 | }
45 |
46 | @Aspect
47 | class ServiceInterceptor {
48 | @Around("execution (* com.example..*(..))")
49 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
50 | Object result = joinPoint.proceed();
51 | System.err.println(joinPoint.toShortString() + ": " + result);
52 | return result;
53 | }
54 | }
55 |
56 | @Aspect
57 | class AnnotationInterceptor {
58 | @Around("@annotation(org.springframework.scheduling.annotation.Async) && execution (* com.example..*(..))")
59 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
60 | Object result = joinPoint.proceed();
61 | System.err.println(joinPoint.toShortString() + ": " + result);
62 | return result;
63 | }
64 | }
65 |
66 | class MultiBeanSelector implements ImportBeanDefinitionRegistrar {
67 |
68 | private static int beans = 0;
69 |
70 | private static int aspects = 0;
71 |
72 | @Override
73 | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
74 | BeanDefinitionRegistry registry) {
75 | DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) registry;
76 | ConfigurableEnvironment environment = (ConfigurableEnvironment) beanFactory
77 | .getSingleton("environment");
78 | int total = environment.getProperty("bench.beans", Integer.class, 0);
79 | for (int i = beans; i < beans + total; i++) {
80 | registry.registerBeanDefinition("service" + i, BeanDefinitionBuilder
81 | .rootBeanDefinition(Service.class).getBeanDefinition());
82 | }
83 | beans += total;
84 | total = environment.getProperty("bench.aspects", Integer.class, 0);
85 | Class> interceptorType = ServiceInterceptor.class;
86 | if (environment.getProperty("bench.annotation", Boolean.class, false)) {
87 | interceptorType = AnnotationInterceptor.class;
88 | }
89 | for (int i = aspects; i < aspects + total; i++) {
90 | registry.registerBeanDefinition("aspect" + i, BeanDefinitionBuilder
91 | .rootBeanDefinition(interceptorType).getBeanDefinition());
92 | }
93 | aspects += total;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/benchmarks/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dsyer/spring-boot-aspectj/79f5f76a398657bd846045b33621375f43c24aef/benchmarks/src/main/resources/application.properties
--------------------------------------------------------------------------------
/benchmarks/src/main/resources/org/aspectj/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/benchmarks/src/test/java/com/bench/ProcessLauncherState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.bench;
17 |
18 | import java.io.BufferedReader;
19 | import java.io.File;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.InputStreamReader;
23 | import java.net.MalformedURLException;
24 | import java.net.URL;
25 | import java.net.URLClassLoader;
26 | import java.nio.file.Paths;
27 | import java.util.ArrayList;
28 | import java.util.Arrays;
29 | import java.util.List;
30 |
31 | import org.openjdk.jmh.util.Utils;
32 | import org.slf4j.Logger;
33 | import org.slf4j.LoggerFactory;
34 | import org.springframework.boot.system.JavaVersion;
35 |
36 | import com.example.InterceptorApplication;
37 |
38 | public class ProcessLauncherState {
39 |
40 | private static final Logger logger = LoggerFactory.getLogger(ProcessLauncherState.class);
41 |
42 | private Process started;
43 | private List args;
44 | private List progArgs;
45 | private List jvmArgs;
46 | private File home;
47 | private String mainClass = InterceptorApplication.class.getName();
48 | private int length;
49 |
50 | public ProcessLauncherState(String dir, String... args) {
51 | this.args = new ArrayList<>(Arrays.asList(args));
52 | int count = 0;
53 | this.args.add(count++, System.getProperty("java.home") + "/bin/java");
54 | this.args.add(count++, "-Xmx128m");
55 | this.args.add(count++, "-cp");
56 | this.args.add(count++, getClasspath());
57 | this.args.add(count++, "-Djava.security.egd=file:/dev/./urandom");
58 | this.args.add(count++, "-XX:TieredStopAtLevel=1"); // zoom
59 | if (System.getProperty("bench.args") != null) {
60 | this.args.addAll(count++, Arrays.asList(System.getProperty("bench.args").split(" ")));
61 | }
62 | this.length = args.length;
63 | this.home = new File(dir);
64 | }
65 |
66 | public void setMainClass(String mainClass) {
67 | this.mainClass = mainClass;
68 | }
69 |
70 | public void setProgArgs(String... extraArgs) {
71 | this.progArgs = Arrays.asList(extraArgs);
72 | }
73 |
74 | public void setJvmArgs(String... extraArgs) {
75 | this.jvmArgs = Arrays.asList(extraArgs);
76 | }
77 |
78 | String getClasspath() {
79 | if (JavaVersion.getJavaVersion().isOlderThan(JavaVersion.NINE)) {
80 | return getClasspathJdk8();
81 | }
82 | return getClasspathJdk9();
83 | }
84 |
85 | String getClasspathJdk8() {
86 | StringBuilder builder = new StringBuilder();
87 |
88 | for (URL url : ((URLClassLoader) getClass().getClassLoader()).getURLs()) {
89 | if (builder.length() > 0) {
90 | builder.append(File.pathSeparator);
91 | }
92 | builder.append(url.toString());
93 | }
94 |
95 | String resultString = builder.toString();
96 | logger.info("Result Classpath: " + resultString);
97 |
98 | return resultString;
99 | }
100 |
101 | String getClasspathJdk9() {
102 | String classpath = System.getProperty("java.class.path");
103 | String[] entries = classpath.split(File.pathSeparator);
104 | URL[] result = new URL[entries.length];
105 |
106 | for (int i = 0; i < entries.length; i++) {
107 | try {
108 | result[i] = Paths.get(entries[i]).toAbsolutePath().toUri().toURL();
109 | } catch (MalformedURLException e) {
110 | logger.error(e.getStackTrace().toString());
111 | }
112 | }
113 |
114 | StringBuilder builder = new StringBuilder();
115 |
116 | for (int i = 0; i < result.length; i++) {
117 | if (builder.length() > 0) {
118 | builder.append(File.pathSeparator);
119 | }
120 | builder.append(result[i]);
121 | }
122 |
123 | String resultString = builder.toString();
124 |
125 | logger.info("Result Classpath: " + resultString);
126 |
127 | return resultString;
128 | }
129 |
130 | public void after() throws Exception {
131 | if (started != null && started.isAlive()) {
132 | System.err.println("Stopped " + mainClass + ": " + started.destroyForcibly().waitFor());
133 | }
134 | }
135 |
136 | public void run() throws Exception {
137 | List args = new ArrayList<>(this.args);
138 | if (jvmArgs != null) {
139 | args.addAll(1, this.jvmArgs);
140 | }
141 | args.add(args.size() - this.length, this.mainClass);
142 | if (progArgs != null) {
143 | args.addAll(progArgs);
144 | }
145 | ProcessBuilder builder = new ProcessBuilder(args);
146 | builder.directory(home);
147 | builder.redirectErrorStream(true);
148 | customize(builder);
149 | if (!"false".equals(System.getProperty("debug", "false"))) {
150 | System.err.println("Running: " + Utils.join(args, " "));
151 | }
152 | started = builder.start();
153 | monitor();
154 | }
155 |
156 | protected void customize(ProcessBuilder builder) {
157 | }
158 |
159 | protected void monitor() throws IOException {
160 | System.out.println(output(started.getInputStream(), "Started"));
161 | }
162 |
163 | protected static String output(InputStream inputStream, String marker) throws IOException {
164 | StringBuilder sb = new StringBuilder();
165 | BufferedReader br = null;
166 | br = new BufferedReader(new InputStreamReader(inputStream));
167 | String line = null;
168 | while ((line = br.readLine()) != null && !line.contains(marker)) {
169 | sb.append(line + System.getProperty("line.separator"));
170 | }
171 | if (line != null) {
172 | sb.append(line + System.getProperty("line.separator"));
173 | }
174 | return sb.toString();
175 | }
176 |
177 | public File getHome() {
178 | return home;
179 | }
180 | }
--------------------------------------------------------------------------------
/benchmarks/src/test/java/com/bench/ProcessLauncherStateTest.java:
--------------------------------------------------------------------------------
1 | package com.bench;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertTrue;
4 |
5 | import org.junit.jupiter.api.Test;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | class ProcessLauncherStateTest {
10 |
11 | private static final Logger logger = LoggerFactory.getLogger(ProcessLauncherStateTest.class);
12 |
13 | private final String CLASSPATH_PART_RESULT = "spring-boot-aspectj/benchmarks/target/test-classes/";
14 |
15 | @Test
16 | void testApplication() throws Exception {
17 | ProcessLauncherState processLauncherState = new ProcessLauncherState("target");
18 | processLauncherState.run();
19 | processLauncherState.after();
20 | }
21 |
22 | @Test
23 | void testGetClasspathJdk8() {
24 | ProcessLauncherState processLauncherState = new ProcessLauncherState("", "");
25 | String classpathName = processLauncherState.getClasspathJdk8();
26 |
27 | logger.info(classpathName);
28 | }
29 |
30 | @Test
31 | void testGetClasspathJdk9() {
32 | ProcessLauncherState processLauncherState = new ProcessLauncherState("", "");
33 | String classpathName = processLauncherState.getClasspathJdk9();
34 |
35 | logger.info(classpathName);
36 |
37 | assertTrue(classpathName.contains(CLASSPATH_PART_RESULT));
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/benchmarks/src/test/java/com/bench/StartupBenchmark.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.bench;
17 |
18 | import org.junit.platform.commons.annotation.Testable;
19 | import org.openjdk.jmh.annotations.AuxCounters;
20 | import org.openjdk.jmh.annotations.AuxCounters.Type;
21 | import org.openjdk.jmh.annotations.Benchmark;
22 | import org.openjdk.jmh.annotations.BenchmarkMode;
23 | import org.openjdk.jmh.annotations.Fork;
24 | import org.openjdk.jmh.annotations.Level;
25 | import org.openjdk.jmh.annotations.Measurement;
26 | import org.openjdk.jmh.annotations.Mode;
27 | import org.openjdk.jmh.annotations.Param;
28 | import org.openjdk.jmh.annotations.Scope;
29 | import org.openjdk.jmh.annotations.Setup;
30 | import org.openjdk.jmh.annotations.State;
31 | import org.openjdk.jmh.annotations.TearDown;
32 | import org.openjdk.jmh.annotations.Warmup;
33 |
34 | import jmh.mbr.junit5.Microbenchmark;
35 |
36 | @Measurement(iterations = 5, time = 1)
37 | @Warmup(iterations = 1, time = 1)
38 | @Fork(value = 2, warmups = 0)
39 | @BenchmarkMode(Mode.AverageTime)
40 | @Microbenchmark
41 | public class StartupBenchmark {
42 |
43 | private static final String M2_REPOSITORY_ASPECTJWEAVER = "/.m2/repository/org/aspectj/aspectjweaver/1.9.5/aspectjweaver-1.9.5.jar";
44 |
45 | @Benchmark
46 | @Testable
47 | public void spring(SpringState state) throws Exception {
48 | state.run();
49 | }
50 |
51 | @Benchmark
52 | @Testable
53 | public void ltw(ApplicationState state) throws Exception {
54 | state.setProgArgs("--spring.aop.auto=false");
55 | state.setJvmArgs("-javaagent:" + home() + M2_REPOSITORY_ASPECTJWEAVER);
56 | state.run();
57 | }
58 |
59 | @Benchmark
60 | @Testable
61 | public void ltw_100(ApplicationState state) throws Exception {
62 | state.setProgArgs("--bench.beans=100", "--spring.aop.auto=false");
63 | state.setJvmArgs("-javaagent:" + home() + M2_REPOSITORY_ASPECTJWEAVER);
64 | state.run();
65 | }
66 |
67 | private String home() {
68 | return System.getProperty("user.home");
69 | }
70 |
71 | @State(Scope.Thread)
72 | @AuxCounters(Type.EVENTS)
73 | public static class SpringState extends ProcessLauncherState {
74 |
75 | public static enum Scale {
76 | v0_10(0, 10), v1_10(1, 10), v1_100(1, 100), v10_50(10, 50), v20_50(20, 50), a0_10(0, 10, true),
77 | a1_10(1, 10, true), a1_100(1, 100, true), a10_50(10, 50, true), a10_100(10, 100, true),
78 | a20_50(20, 50, true);
79 |
80 | private int beans;
81 | private int aspects;
82 | private boolean annotation;
83 |
84 | private Scale(int aspects, int beans) {
85 | this(aspects, beans, false);
86 | }
87 |
88 | private Scale(int aspects, int beans, boolean annotation) {
89 | this.beans = beans;
90 | this.aspects = aspects;
91 | this.annotation = annotation;
92 | }
93 |
94 | public String[] getArgs() {
95 | return new String[] { "--server.port=0", "--bench.aspects=" + aspects, "--bench.beans=" + beans,
96 | "--bench.annotation=" + annotation };
97 | }
98 | }
99 |
100 | @Param // ("a1_100")
101 | private Scale scale = Scale.v1_10;
102 |
103 | public SpringState() {
104 | super("target");
105 | }
106 |
107 | @Setup(Level.Trial)
108 | public void start() throws Exception {
109 | setProgArgs(scale.getArgs());
110 | }
111 |
112 | @TearDown(Level.Invocation)
113 | public void stop() throws Exception {
114 | super.after();
115 | }
116 | }
117 |
118 | @State(Scope.Thread)
119 | @AuxCounters(Type.EVENTS)
120 | public static class ApplicationState extends ProcessLauncherState {
121 |
122 | public ApplicationState() {
123 | super("target", "--server.port=0");
124 | }
125 |
126 | @TearDown(Level.Invocation)
127 | public void stop() throws Exception {
128 | super.after();
129 | }
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/benchmarks/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest(properties="logging.level.org.springframework.aop=TRACE")
7 | public class InterceptorApplicationTests {
8 |
9 | @Test
10 | public void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/ctw/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | ctw
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ctw
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 | 1.0.24.RELEASE
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-actuator
32 |
33 |
34 | org.springframework
35 | spring-aop
36 |
37 |
38 | org.aspectj
39 | aspectjrt
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-web
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-configuration-processor
48 | true
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 | org.springframework.boot.experimental
67 | spring-boot-thin-layout
68 | ${thin-jar.version}
69 |
70 |
71 | org.aspectj
72 | aspectjweaver
73 | ${aspectj.version}
74 |
75 |
76 |
77 |
78 |
79 | org.eclipse.m2e
80 | lifecycle-mapping
81 | 1.0.0
82 |
83 |
84 |
85 |
86 |
87 |
88 | com.nickwongdev
89 |
90 |
91 | aspectj-maven-plugin
92 |
93 |
94 | [1.10,)
95 |
96 |
97 | compile
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | org.springframework.boot
113 | spring-boot-maven-plugin
114 |
115 |
116 | com.nickwongdev
117 | aspectj-maven-plugin
118 | 1.12.6
119 |
120 | ${java.version}
121 | ${java.version}
122 | none
123 | ${java.version}
124 | true
125 |
126 |
127 |
128 |
129 | compile
130 |
131 |
132 |
133 |
134 |
135 | org.aspectj
136 | aspectjtools
137 | ${aspectj.version}
138 |
139 |
140 |
141 |
142 | org.apache.maven.plugins
143 | maven-deploy-plugin
144 |
145 | true
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 | spring-snapshots
154 | Spring Snapshots
155 | https://repo.spring.io/snapshot
156 |
157 | true
158 |
159 |
160 |
161 | spring-milestones
162 | Spring Milestones
163 | https://repo.spring.io/milestone
164 |
165 | false
166 |
167 |
168 |
169 |
170 |
171 | spring-snapshots
172 | Spring Snapshots
173 | https://repo.spring.io/snapshot
174 |
175 | true
176 |
177 |
178 |
179 | spring-milestones
180 | Spring Milestones
181 | https://repo.spring.io/milestone
182 |
183 | false
184 |
185 |
186 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/ctw/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.context.event.ContextRefreshedEvent;
10 | import org.springframework.context.event.EventListener;
11 |
12 | @Aspect
13 | @ConfigurationProperties("interceptor")
14 | public class Interceptor {
15 |
16 | private static final Logger logger = LoggerFactory.getLogger(Interceptor.class);
17 |
18 | /**
19 | * Message to print on startup
20 | */
21 | private String message = "Startup";
22 |
23 | public String getMessage() {
24 | return message;
25 | }
26 |
27 | public void setMessage(String message) {
28 | this.message = message;
29 | }
30 |
31 | @Around("execution(* *(..)) && !within(com.example.Interceptor)"
32 | + " && (within(org.springframework.context.annotation.Condition+) || within(com.example..*))")
33 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
34 | Object result = joinPoint.proceed();
35 | logger.debug("AspectJ intercept: " + joinPoint.toShortString() + ": " + result);
36 | return result;
37 | }
38 |
39 | @Around("execution(* *(..)) && within(com.example..*) && !within(com.example.Interceptor+)")
40 | public Object stack(ProceedingJoinPoint joinPoint) throws Throwable {
41 | logger.debug("AspectJ stack: " + joinPoint.toShortString());
42 | return joinPoint.proceed();
43 | }
44 |
45 | @EventListener
46 | public void started(ContextRefreshedEvent event) {
47 | logger.debug("AspectJ started: " + message + ": " + event);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/ctw/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.Aspects;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | @SpringBootApplication
11 | @RestController
12 | public class InterceptorApplication {
13 |
14 | @RequestMapping("/")
15 | public String home() {
16 | return "Hello World";
17 | }
18 |
19 | @Bean
20 | public Interceptor interceptor() {
21 | // This will barf at runtime if the weaver isn't working (probably a
22 | // good thing)
23 | return Aspects.aspectOf(Interceptor.class);
24 | }
25 |
26 | public static void main(String[] args) {
27 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ctw/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.aop.auto=false
2 |
3 | logging.level.com.example=DEBUG
--------------------------------------------------------------------------------
/ctw/src/main/resources/org/aspectj/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ctw/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class InterceptorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/ltw/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.example
8 | ltw
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | ltw
13 | Demo project for Spring Boot
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.2.4.RELEASE
19 |
20 |
21 |
22 |
23 | UTF-8
24 | UTF-8
25 | 8
26 | 1.0.24.RELEASE
27 |
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-actuator
33 |
34 |
35 | org.springframework
36 | spring-aop
37 |
38 |
39 | org.aspectj
40 | aspectjrt
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-starter-web
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-configuration-processor
49 | true
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-starter-test
55 | test
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-maven-plugin
65 |
66 |
67 | ${project.build.directory}/aspectj/aspectjweaver-${aspectj.version}.jar
68 |
69 |
70 |
71 |
72 | org.springframework.boot.experimental
73 | spring-boot-thin-layout
74 | ${thin-jar.version}
75 |
76 |
77 | org.aspectj
78 | aspectjweaver
79 | ${aspectj.version}
80 |
81 |
82 |
83 |
84 | org.apache.maven.plugins
85 | maven-surefire-plugin
86 |
87 | -javaagent:${project.build.directory}/aspectj/aspectjweaver-${aspectj.version}.jar
88 |
89 |
90 |
91 |
92 |
93 |
94 | org.springframework.boot
95 | spring-boot-maven-plugin
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-deploy-plugin
100 |
101 | true
102 |
103 |
104 |
105 | org.apache.maven.plugins
106 | maven-dependency-plugin
107 |
108 |
109 | copy
110 | initialize
111 |
112 | copy
113 |
114 |
115 |
116 |
117 |
118 |
119 | org.aspectj
120 | aspectjweaver
121 | ${aspectj.version}
122 | jar
123 | false
124 | ${project.build.directory}/aspectj
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | spring-snapshots
135 | Spring Snapshots
136 | https://repo.spring.io/snapshot
137 |
138 | true
139 |
140 |
141 |
142 | spring-milestones
143 | Spring Milestones
144 | https://repo.spring.io/milestone
145 |
146 | false
147 |
148 |
149 |
150 |
151 |
152 | spring-snapshots
153 | Spring Snapshots
154 | https://repo.spring.io/snapshot
155 |
156 | true
157 |
158 |
159 |
160 | spring-milestones
161 | Spring Milestones
162 | https://repo.spring.io/milestone
163 |
164 | false
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/ltw/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.context.event.ContextRefreshedEvent;
10 | import org.springframework.context.event.EventListener;
11 |
12 | @Aspect
13 | @ConfigurationProperties("interceptor")
14 | public class Interceptor {
15 |
16 | private static final Logger logger = LoggerFactory.getLogger(Interceptor.class);
17 |
18 | /**
19 | * Message to print on startup
20 | */
21 | private String message = "Startup";
22 |
23 | public String getMessage() {
24 | return message;
25 | }
26 |
27 | public void setMessage(String message) {
28 | this.message = message;
29 | }
30 |
31 | @Around("execution(* *(..)) && !within(com.example.Interceptor)"
32 | + " && (within(org.springframework.context.annotation.Condition+) || within(com.example..*))")
33 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
34 | Object result = joinPoint.proceed();
35 | logger.debug("AspectJ intercept: " + joinPoint.toShortString() + ": " + result);
36 | return result;
37 | }
38 |
39 | @Around("execution(* *(..)) && within(com.example..*) && !within(com.example.Interceptor+)")
40 | public Object stack(ProceedingJoinPoint joinPoint) throws Throwable {
41 | logger.debug("AspectJ stack: " + joinPoint.toShortString());
42 | return joinPoint.proceed();
43 | }
44 |
45 | @EventListener
46 | public void started(ContextRefreshedEvent event) {
47 | logger.debug("AspectJ started: " + message + ": " + event);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/ltw/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.Aspects;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | @SpringBootApplication
11 | @RestController
12 | public class InterceptorApplication {
13 |
14 | @RequestMapping("/")
15 | public String home() {
16 | return "Hello World";
17 | }
18 |
19 | @Bean
20 | public Interceptor interceptor() {
21 | // This will barf at runtime if the weaver isn't working (probably a
22 | // good thing)
23 | return Aspects.aspectOf(Interceptor.class);
24 | }
25 |
26 | public static void main(String[] args) {
27 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ltw/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.aop.auto=false
2 |
3 | logging.level.com.example=DEBUG
--------------------------------------------------------------------------------
/ltw/src/main/resources/org/aspectj/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ltw/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class InterceptorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | ctw-app
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ctw-app
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 | 1.0.24.RELEASE
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-actuator
32 |
33 |
34 | com.example
35 | ctw-aspects
36 | ${project.version}
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-web
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-configuration-processor
45 | true
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-test
51 | test
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-maven-plugin
61 |
62 |
63 | org.springframework.boot.experimental
64 | spring-boot-thin-layout
65 | ${thin-jar.version}
66 |
67 |
68 |
69 |
70 |
71 | org.eclipse.m2e
72 | lifecycle-mapping
73 | 1.0.0
74 |
75 |
76 |
77 |
78 |
79 |
80 | com.nickwongdev
81 |
82 |
83 | aspectj-maven-plugin
84 |
85 |
86 | [1.10,)
87 |
88 |
89 | compile
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | org.springframework.boot
105 | spring-boot-maven-plugin
106 |
107 |
108 | com.nickwongdev
109 | aspectj-maven-plugin
110 | 1.12.6
111 |
112 | ${java.version}
113 | ${java.version}
114 | none
115 | ${java.version}
116 | true
117 |
118 |
119 | com.example
120 | ctw-aspects
121 |
122 |
123 |
124 |
125 |
126 |
127 | compile
128 |
129 |
130 |
131 |
132 |
133 | org.aspectj
134 | aspectjtools
135 | ${aspectj.version}
136 |
137 |
138 |
139 |
140 | org.apache.maven.plugins
141 | maven-deploy-plugin
142 |
143 | true
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | spring-snapshots
152 | Spring Snapshots
153 | https://repo.spring.io/snapshot
154 |
155 | true
156 |
157 |
158 |
159 | spring-milestones
160 | Spring Milestones
161 | https://repo.spring.io/milestone
162 |
163 | false
164 |
165 |
166 |
167 |
168 |
169 | spring-snapshots
170 | Spring Snapshots
171 | https://repo.spring.io/snapshot
172 |
173 | true
174 |
175 |
176 |
177 | spring-milestones
178 | Spring Milestones
179 | https://repo.spring.io/milestone
180 |
181 | false
182 |
183 |
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-app/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.Aspects;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | @SpringBootApplication
11 | @RestController
12 | public class InterceptorApplication {
13 |
14 | @RequestMapping("/")
15 | public String home() {
16 | return "Hello World";
17 | }
18 |
19 | @Bean
20 | public Interceptor interceptor() {
21 | // This will barf at runtime if the weaver isn't working (probably a
22 | // good thing)
23 | return Aspects.aspectOf(Interceptor.class);
24 | }
25 |
26 | public static void main(String[] args) {
27 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.aop.auto=false
2 |
3 | logging.level.com.example=DEBUG
--------------------------------------------------------------------------------
/multi-ctw/ctw-app/src/main/resources/org/aspectj/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-app/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class InterceptorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-aspects/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | ctw-aspects
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ctw-aspects
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 | 1.0.24.RELEASE
26 |
27 |
28 |
29 |
30 | org.springframework
31 | spring-aop
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter
36 |
37 |
38 | org.aspectj
39 | aspectjrt
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-configuration-processor
44 | true
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 | com.nickwongdev
58 | aspectj-maven-plugin
59 | 1.12.6
60 |
61 | ${java.version}
62 | ${java.version}
63 | none
64 | ${java.version}
65 | true
66 |
67 |
68 |
69 |
70 | compile
71 |
72 |
73 |
74 |
75 |
76 | org.aspectj
77 | aspectjtools
78 | ${aspectj.version}
79 |
80 |
81 |
82 |
83 | org.apache.maven.plugins
84 | maven-deploy-plugin
85 |
86 | true
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | org.eclipse.m2e
95 | lifecycle-mapping
96 | 1.0.0
97 |
98 |
99 |
100 |
101 |
102 |
103 | com.nickwongdev
104 |
105 |
106 | aspectj-maven-plugin
107 |
108 |
109 | [1.10,)
110 |
111 |
112 | compile
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | spring-snapshots
130 | Spring Snapshots
131 | https://repo.spring.io/snapshot
132 |
133 | true
134 |
135 |
136 |
137 | spring-milestones
138 | Spring Milestones
139 | https://repo.spring.io/milestone
140 |
141 | false
142 |
143 |
144 |
145 |
146 |
147 | spring-snapshots
148 | Spring Snapshots
149 | https://repo.spring.io/snapshot
150 |
151 | true
152 |
153 |
154 |
155 | spring-milestones
156 | Spring Milestones
157 | https://repo.spring.io/milestone
158 |
159 | false
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/multi-ctw/ctw-aspects/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.context.event.ContextRefreshedEvent;
10 | import org.springframework.context.event.EventListener;
11 |
12 | @Aspect
13 | @ConfigurationProperties("interceptor")
14 | public class Interceptor {
15 |
16 | private static final Logger logger = LoggerFactory.getLogger(Interceptor.class);
17 |
18 | /**
19 | * Message to print on startup
20 | */
21 | private String message = "Startup";
22 |
23 | public String getMessage() {
24 | return message;
25 | }
26 |
27 | public void setMessage(String message) {
28 | this.message = message;
29 | }
30 |
31 | @Around("execution(* *(..)) && !within(com.example.Interceptor)"
32 | + " && (within(org.springframework.context.annotation.Condition+) || within(com.example..*))")
33 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
34 | Object result = joinPoint.proceed();
35 | logger.debug("AspectJ intercept: " + joinPoint.toShortString() + ": " + result);
36 | return result;
37 | }
38 |
39 | @Around("execution(* *(..)) && within(com.example..*) && !within(com.example.Interceptor+)")
40 | public Object stack(ProceedingJoinPoint joinPoint) throws Throwable {
41 | logger.debug("AspectJ stack: " + joinPoint.toShortString());
42 | return joinPoint.proceed();
43 | }
44 |
45 | @EventListener
46 | public void started(ContextRefreshedEvent event) {
47 | logger.debug("AspectJ started: " + message + ": " + event);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/multi-ctw/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.4.RELEASE
9 |
10 |
11 |
12 | com.example
13 | multi-ctw
14 | 0.0.1-SNAPSHOT
15 | pom
16 | multi-ctw
17 |
18 |
19 | ctw-aspects
20 | ctw-app
21 |
22 |
23 |
24 | 8
25 |
26 |
27 |
28 |
29 |
30 | org.apache.maven.plugins
31 | maven-deploy-plugin
32 |
33 | true
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | spring-libs-snapshot
42 | http://repo.spring.io/libs-snapshot
43 |
44 | true
45 |
46 |
47 | true
48 |
49 |
50 |
51 |
52 |
53 |
54 | spring-libs-snapshot
55 | http://repo.spring.io/libs-snapshot
56 |
57 | true
58 |
59 |
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.example
8 | ltw-app
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | ltw-app
13 | Demo project for Spring Boot
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.2.4.RELEASE
19 |
20 |
21 |
22 |
23 | UTF-8
24 | UTF-8
25 | 8
26 | 1.0.24.RELEASE
27 | 1.0.0-SNAPSHOT
28 |
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-actuator
34 |
35 |
36 | com.example
37 | ltw-aspects
38 | ${project.version}
39 |
40 |
41 | com.example
42 | timing
43 | ${timing.version}
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-web
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-configuration-processor
52 | true
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-starter-test
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-maven-plugin
68 |
69 |
70 | org.springframework.boot.experimental
71 | spring-boot-thin-layout
72 | ${thin-jar.version}
73 |
74 |
75 | org.aspectj
76 | aspectjweaver
77 | ${aspectj.version}
78 |
79 |
80 |
81 |
82 | org.apache.maven.plugins
83 | maven-surefire-plugin
84 |
85 | -javaagent:${project.build.directory}/aspectj/aspectjweaver-${aspectj.version}.jar
86 |
87 |
88 |
89 | org.codehaus.mojo
90 | aspectj-maven-plugin
91 |
92 | true
93 |
94 |
95 |
96 |
97 |
98 |
99 | org.springframework.boot
100 | spring-boot-maven-plugin
101 |
102 |
103 | ${project.build.directory}/aspectj/aspectjweaver-${aspectj.version}.jar
104 |
105 |
106 |
107 |
108 | org.apache.maven.plugins
109 | maven-deploy-plugin
110 |
111 | true
112 |
113 |
114 |
115 | org.apache.maven.plugins
116 | maven-dependency-plugin
117 |
118 |
119 | copy
120 | initialize
121 |
122 | copy
123 |
124 |
125 |
126 |
127 |
128 |
129 | org.aspectj
130 | aspectjweaver
131 | ${aspectj.version}
132 | jar
133 | false
134 | ${project.build.directory}/aspectj
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | spring-snapshots
145 | Spring Snapshots
146 | https://repo.spring.io/snapshot
147 |
148 | true
149 |
150 |
151 |
152 | spring-milestones
153 | Spring Milestones
154 | https://repo.spring.io/milestone
155 |
156 | false
157 |
158 |
159 |
160 |
161 |
162 | spring-snapshots
163 | Spring Snapshots
164 | https://repo.spring.io/snapshot
165 |
166 | true
167 |
168 |
169 |
170 | spring-milestones
171 | Spring Milestones
172 | https://repo.spring.io/milestone
173 |
174 | false
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-app/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.Aspects;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | @SpringBootApplication
11 | @RestController
12 | public class InterceptorApplication {
13 |
14 | @RequestMapping("/")
15 | public String home() {
16 | return "Hello World";
17 | }
18 |
19 | @Bean
20 | public Interceptor interceptor() {
21 | // This will barf at runtime if the weaver isn't working (probably a
22 | // good thing)
23 | return Aspects.aspectOf(Interceptor.class);
24 | }
25 |
26 | public static void main(String[] args) {
27 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.aop.auto=false
2 |
3 | logging.level.com.example=DEBUG
--------------------------------------------------------------------------------
/multi-ltw/ltw-app/src/main/resources/org/aspectj/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-app/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class InterceptorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-aspects/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | ltw-aspects
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ltw-aspects
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 | 1.0.24.RELEASE
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter
32 |
33 |
34 | org.springframework
35 | spring-aop
36 |
37 |
38 | org.aspectj
39 | aspectjrt
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-configuration-processor
44 | true
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-deploy-plugin
59 |
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | spring-snapshots
69 | Spring Snapshots
70 | https://repo.spring.io/snapshot
71 |
72 | true
73 |
74 |
75 |
76 | spring-milestones
77 | Spring Milestones
78 | https://repo.spring.io/milestone
79 |
80 | false
81 |
82 |
83 |
84 |
85 |
86 | spring-snapshots
87 | Spring Snapshots
88 | https://repo.spring.io/snapshot
89 |
90 | true
91 |
92 |
93 |
94 | spring-milestones
95 | Spring Milestones
96 | https://repo.spring.io/milestone
97 |
98 | false
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/multi-ltw/ltw-aspects/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.context.event.ContextRefreshedEvent;
10 | import org.springframework.context.event.EventListener;
11 |
12 | @Aspect
13 | @ConfigurationProperties("interceptor")
14 | public class Interceptor {
15 |
16 | private static final Logger logger = LoggerFactory.getLogger(Interceptor.class);
17 |
18 | /**
19 | * Message to print on startup
20 | */
21 | private String message = "Startup";
22 |
23 | public String getMessage() {
24 | return message;
25 | }
26 |
27 | public void setMessage(String message) {
28 | this.message = message;
29 | }
30 |
31 | @Around("execution(* *(..)) && !within(com.example.Interceptor)"
32 | + " && (within(org.springframework.context.annotation.Condition+) || within(com.example..*))")
33 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
34 | Object result = joinPoint.proceed();
35 | logger.debug("AspectJ intercept: " + joinPoint.toShortString() + ": " + result);
36 | return result;
37 | }
38 |
39 | @Around("execution(* *(..)) && within(com.example..*) && !within(com.example.Interceptor+)")
40 | public Object stack(ProceedingJoinPoint joinPoint) throws Throwable {
41 | logger.debug("AspectJ stack: " + joinPoint.toShortString());
42 | return joinPoint.proceed();
43 | }
44 |
45 | @EventListener
46 | public void started(ContextRefreshedEvent event) {
47 | logger.debug("AspectJ started: " + message + ": " + event);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/multi-ltw/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.4.RELEASE
9 |
10 |
11 |
12 | com.example
13 | multi-ltw
14 | 0.0.1-SNAPSHOT
15 | pom
16 | multi-ltw
17 |
18 |
19 | ltw-aspects
20 | ltw-app
21 |
22 |
23 |
24 | 8
25 |
26 |
27 |
28 |
29 |
30 | org.apache.maven.plugins
31 | maven-deploy-plugin
32 |
33 | true
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | spring-libs-snapshot
42 | http://repo.spring.io/libs-snapshot
43 |
44 | true
45 |
46 |
47 | true
48 |
49 |
50 |
51 |
52 |
53 |
54 | spring-libs-snapshot
55 | http://repo.spring.io/libs-snapshot
56 |
57 | true
58 |
59 |
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | #
58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look
59 | # for the new JDKs provided by Oracle.
60 | #
61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
62 | #
63 | # Apple JDKs
64 | #
65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
66 | fi
67 |
68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
69 | #
70 | # Apple JDKs
71 | #
72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
73 | fi
74 |
75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
76 | #
77 | # Oracle JDKs
78 | #
79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
80 | fi
81 |
82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
83 | #
84 | # Apple JDKs
85 | #
86 | export JAVA_HOME=`/usr/libexec/java_home`
87 | fi
88 | ;;
89 | esac
90 |
91 | if [ -z "$JAVA_HOME" ] ; then
92 | if [ -r /etc/gentoo-release ] ; then
93 | JAVA_HOME=`java-config --jre-home`
94 | fi
95 | fi
96 |
97 | if [ -z "$M2_HOME" ] ; then
98 | ## resolve links - $0 may be a link to maven's home
99 | PRG="$0"
100 |
101 | # need this for relative symlinks
102 | while [ -h "$PRG" ] ; do
103 | ls=`ls -ld "$PRG"`
104 | link=`expr "$ls" : '.*-> \(.*\)$'`
105 | if expr "$link" : '/.*' > /dev/null; then
106 | PRG="$link"
107 | else
108 | PRG="`dirname "$PRG"`/$link"
109 | fi
110 | done
111 |
112 | saveddir=`pwd`
113 |
114 | M2_HOME=`dirname "$PRG"`/..
115 |
116 | # make it fully qualified
117 | M2_HOME=`cd "$M2_HOME" && pwd`
118 |
119 | cd "$saveddir"
120 | # echo Using m2 at $M2_HOME
121 | fi
122 |
123 | # For Cygwin, ensure paths are in UNIX format before anything is touched
124 | if $cygwin ; then
125 | [ -n "$M2_HOME" ] &&
126 | M2_HOME=`cygpath --unix "$M2_HOME"`
127 | [ -n "$JAVA_HOME" ] &&
128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
129 | [ -n "$CLASSPATH" ] &&
130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
131 | fi
132 |
133 | # For Migwn, ensure paths are in UNIX format before anything is touched
134 | if $mingw ; then
135 | [ -n "$M2_HOME" ] &&
136 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
137 | [ -n "$JAVA_HOME" ] &&
138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
139 | # TODO classpath?
140 | fi
141 |
142 | if [ -z "$JAVA_HOME" ]; then
143 | javaExecutable="`which javac`"
144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
145 | # readlink(1) is not available as standard on Solaris 10.
146 | readLink=`which readlink`
147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
148 | if $darwin ; then
149 | javaHome="`dirname \"$javaExecutable\"`"
150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
151 | else
152 | javaExecutable="`readlink -f \"$javaExecutable\"`"
153 | fi
154 | javaHome="`dirname \"$javaExecutable\"`"
155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
156 | JAVA_HOME="$javaHome"
157 | export JAVA_HOME
158 | fi
159 | fi
160 | fi
161 |
162 | if [ -z "$JAVACMD" ] ; then
163 | if [ -n "$JAVA_HOME" ] ; then
164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
165 | # IBM's JDK on AIX uses strange locations for the executables
166 | JAVACMD="$JAVA_HOME/jre/sh/java"
167 | else
168 | JAVACMD="$JAVA_HOME/bin/java"
169 | fi
170 | else
171 | JAVACMD="`which java`"
172 | fi
173 | fi
174 |
175 | if [ ! -x "$JAVACMD" ] ; then
176 | echo "Error: JAVA_HOME is not defined correctly." >&2
177 | echo " We cannot execute $JAVACMD" >&2
178 | exit 1
179 | fi
180 |
181 | if [ -z "$JAVA_HOME" ] ; then
182 | echo "Warning: JAVA_HOME environment variable is not set."
183 | fi
184 |
185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
186 |
187 | # For Cygwin, switch paths to Windows format before running java
188 | if $cygwin; then
189 | [ -n "$M2_HOME" ] &&
190 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
191 | [ -n "$JAVA_HOME" ] &&
192 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
193 | [ -n "$CLASSPATH" ] &&
194 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
195 | fi
196 |
197 | # traverses directory structure from process work directory to filesystem root
198 | # first directory with .mvn subdirectory is considered project base directory
199 | find_maven_basedir() {
200 | local basedir=$(pwd)
201 | local wdir=$(pwd)
202 | while [ "$wdir" != '/' ] ; do
203 | if [ -d "$wdir"/.mvn ] ; then
204 | basedir=$wdir
205 | break
206 | fi
207 | wdir=$(cd "$wdir/.."; pwd)
208 | done
209 | echo "${basedir}"
210 | }
211 |
212 | # concatenates all lines of a file
213 | concat_lines() {
214 | if [ -f "$1" ]; then
215 | echo "$(tr -s '\n' ' ' < "$1")"
216 | fi
217 | }
218 |
219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
221 |
222 | # Provide a "standardized" way to retrieve the CLI args that will
223 | # work with both Windows and non-Windows executions.
224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
225 | export MAVEN_CMD_LINE_ARGS
226 |
227 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
228 |
229 | echo "Running version check"
230 | VERSION=$( sed '\!//' -e 's!.*$!!' )
231 | echo "The found version is [${VERSION}]"
232 |
233 | if echo $VERSION | egrep -q 'M|RC'; then
234 | echo Activating \"milestone\" profile for version=\"$VERSION\"
235 | echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
236 | else
237 | echo Deactivating \"milestone\" profile for version=\"$VERSION\"
238 | echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
239 | fi
240 |
241 | if echo $VERSION | egrep -q 'RELEASE'; then
242 | echo Activating \"central\" profile for version=\"$VERSION\"
243 | echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
244 | else
245 | echo Deactivating \"central\" profile for version=\"$VERSION\"
246 | echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
247 | fi
248 |
249 | exec "$JAVACMD" \
250 | $MAVEN_OPTS \
251 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
252 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
253 | ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
254 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
146 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.4.RELEASE
9 |
10 |
11 | com.example
12 | spring-boot-aspectj
13 | 0.0.1-SNAPSHOT
14 | pom
15 | spring-boot-aspectj
16 |
17 |
18 | timing
19 | spring
20 | ltw
21 | ctw
22 | multi-ltw
23 | multi-ctw
24 | benchmarks
25 |
26 |
27 |
28 | 11
29 |
30 |
31 |
32 |
33 |
34 | org.apache.maven.plugins
35 | maven-deploy-plugin
36 |
37 | true
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | spring-libs-snapshot
46 | http://repo.spring.io/libs-snapshot
47 |
48 | true
49 |
50 |
51 | true
52 |
53 |
54 |
55 |
56 |
57 |
58 | spring-libs-snapshot
59 | http://repo.spring.io/libs-snapshot
60 |
61 | true
62 |
63 |
64 | true
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/spring/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | spring
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | spring
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 | 1.0.24.RELEASE
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-actuator
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-aop
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-web
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-configuration-processor
44 | true
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-maven-plugin
60 |
61 |
62 | org.springframework.boot.experimental
63 | spring-boot-thin-layout
64 | ${thin-jar.version}
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | org.springframework.boot
73 | spring-boot-maven-plugin
74 |
75 |
76 | org.apache.maven.plugins
77 | maven-deploy-plugin
78 |
79 | true
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | spring-snapshots
88 | Spring Snapshots
89 | https://repo.spring.io/snapshot
90 |
91 | true
92 |
93 |
94 |
95 | spring-milestones
96 | Spring Milestones
97 | https://repo.spring.io/milestone
98 |
99 | false
100 |
101 |
102 |
103 |
104 |
105 | spring-snapshots
106 | Spring Snapshots
107 | https://repo.spring.io/snapshot
108 |
109 | true
110 |
111 |
112 |
113 | spring-milestones
114 | Spring Milestones
115 | https://repo.spring.io/milestone
116 |
117 | false
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/spring/src/main/java/com/example/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 | import org.aspectj.lang.annotation.Around;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.context.event.ContextRefreshedEvent;
10 | import org.springframework.context.event.EventListener;
11 | import org.springframework.stereotype.Component;
12 |
13 | @Aspect
14 | @ConfigurationProperties("interceptor")
15 | @Component
16 | public class Interceptor {
17 |
18 | private static final Logger logger = LoggerFactory.getLogger(Interceptor.class);
19 |
20 | /**
21 | * Message to print on startup
22 | */
23 | private String message = "Startup";
24 |
25 | public String getMessage() {
26 | return message;
27 | }
28 |
29 | public void setMessage(String message) {
30 | this.message = message;
31 | }
32 |
33 | @Around("execution(* *.*(..)) && within(com.example..*)")
34 | public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
35 | Object result = joinPoint.proceed();
36 | logger.debug("AspectJ intercept: " + joinPoint.toShortString() + ": " + result);
37 | return result;
38 | }
39 |
40 | @Around("execution(* *.*(..)) && within(com.example..*)")
41 | public Object another(ProceedingJoinPoint joinPoint) throws Throwable {
42 | Object result = joinPoint.proceed();
43 | logger.debug("AspectJ another: " + joinPoint.toShortString() + ": " + result);
44 | return result;
45 | }
46 |
47 | @EventListener
48 | public void started(ContextRefreshedEvent event) {
49 | logger.debug("AspectJ started: " + message + ": " + event);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/spring/src/main/java/com/example/InterceptorApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @SpringBootApplication
9 | @RestController
10 | public class InterceptorApplication {
11 |
12 | @RequestMapping("/")
13 | public String home() {
14 | return "Hello World";
15 | }
16 |
17 | public static void main(String[] args) {
18 | new SpringApplicationBuilder(InterceptorApplication.class).run(args);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/spring/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | logging.level.com.example=DEBUG
--------------------------------------------------------------------------------
/spring/src/test/java/com/example/InterceptorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest(properties = { "logging.level.org.springframework.aop=TRACE", "logging.level.com.example=DEBUG" })
10 | public class InterceptorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/timing/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/timing/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dsyer/spring-boot-aspectj/79f5f76a398657bd846045b33621375f43c24aef/timing/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/timing/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip
2 |
--------------------------------------------------------------------------------
/timing/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/timing/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/timing/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | timing
8 | 1.0.0-SNAPSHOT
9 | jar
10 |
11 | timing
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter
31 |
32 |
33 | org.aspectj
34 | aspectjrt
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-test
40 | test
41 |
42 |
43 |
44 |
45 | https://github.com/dsyer/spring-boot-aspectj
46 |
47 | spring-docs
48 | scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-boot/docs/${project.artifactId}/${project.version}
49 |
50 |
51 | sonatype-nexus-staging
52 | Nexus Release Repository
53 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
54 |
55 |
56 | repo.spring.io
57 | Spring Snapshot Repository
58 | https://repo.spring.io/libs-snapshot-local
59 |
60 |
61 |
62 |
63 | milestone
64 |
65 |
66 | repo.spring.io
67 | Spring Milestone Repository
68 | https://repo.spring.io/libs-milestone-local
69 |
70 |
71 |
72 |
73 | central
74 |
75 |
76 |
77 | org.apache.maven.plugins
78 | maven-gpg-plugin
79 |
80 |
81 | sign-artifacts
82 | verify
83 |
84 | sign
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/timing/src/main/java/org/springframework/boot/aspects/AspectConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.boot.aspects;
17 |
18 | import org.aspectj.lang.Aspects;
19 |
20 | import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
22 | import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
23 | import org.springframework.context.annotation.Bean;
24 | import org.springframework.context.annotation.ConditionContext;
25 | import org.springframework.context.annotation.Conditional;
26 | import org.springframework.context.annotation.Configuration;
27 | import org.springframework.core.type.AnnotatedTypeMetadata;
28 |
29 | /**
30 | * @author Dave Syer
31 | *
32 | */
33 | @Configuration
34 | public class AspectConfiguration {
35 |
36 | @Bean
37 | @Conditional(AspectsCondition.class)
38 | @ConditionalOnClass(name = "org.aspectj.lang.Aspects")
39 | public TimingInterceptor timingInterceptor() {
40 | return Aspects.aspectOf(TimingInterceptor.class);
41 | }
42 |
43 | private static class AspectsCondition extends SpringBootCondition {
44 |
45 | @Override
46 | public ConditionOutcome getMatchOutcome(ConditionContext context,
47 | AnnotatedTypeMetadata metadata) {
48 | if (Aspects.hasAspect(TimingInterceptor.class)) {
49 | return ConditionOutcome.match("AspectJ weaving");
50 | }
51 | return ConditionOutcome.noMatch("AspectJ not weaving");
52 | }
53 |
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/timing/src/main/java/org/springframework/boot/aspects/TimingInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.boot.aspects;
17 |
18 | import org.aspectj.lang.ProceedingJoinPoint;
19 | import org.aspectj.lang.annotation.Around;
20 | import org.aspectj.lang.annotation.Aspect;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 | import org.springframework.context.event.ContextRefreshedEvent;
24 | import org.springframework.context.event.EventListener;
25 | import org.springframework.util.StopWatch;
26 |
27 | /**
28 | * @author Dave Syer
29 | *
30 | */
31 | @Aspect
32 | public class TimingInterceptor {
33 |
34 | private static final Logger logger = LoggerFactory.getLogger(TimingInterceptor.class);
35 |
36 | private StopWatch bind = new StopWatch("bind");
37 |
38 | private StopWatch init = new StopWatch("init");
39 |
40 | private StopWatch app = new StopWatch("app");
41 |
42 | private int level = 0;
43 |
44 | @Around("execution(private * org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(Object, String, ..)) && args(bean,..)")
45 | public Object bind(ProceedingJoinPoint joinPoint, Object bean) throws Throwable {
46 | bind.start();
47 | Object result = joinPoint.proceed();
48 | bind.stop();
49 | logger.debug("Bind,," + bean.getClass().getName() + ": " + bind.getLastTaskTimeMillis());
50 | return result;
51 | }
52 |
53 | @Around("execution(* org.springframework.beans.factory.config.BeanPostProcessor+.*(Object, String)) && args(bean,..)")
54 | public Object post(ProceedingJoinPoint joinPoint, Object bean) throws Throwable {
55 | long t0 = System.nanoTime();
56 | Object result = joinPoint.proceed();
57 | long t1 = System.nanoTime();
58 | logger.info("Post," + joinPoint.getSignature().getDeclaringType().getSimpleName()
59 | + "." + joinPoint.getSignature().getName() + ","
60 | + bean.getClass().getName() + "," + (t1 - t0) / 1000000.);
61 | return result;
62 | }
63 |
64 | @Around("execution(* org.springframework.boot.SpringApplication+.*(..))")
65 | public Object initializer(ProceedingJoinPoint joinPoint) throws Throwable {
66 | String task = app.currentTaskName();
67 | if (task != null) {
68 | app.stop();
69 | }
70 | long t0 = System.nanoTime();
71 | level++;
72 | app.start(joinPoint.getSignature().getName());
73 | Object result = joinPoint.proceed();
74 | long t1 = System.nanoTime();
75 | app.stop();
76 | if (task != null) {
77 | app.start(task);
78 | }
79 | logger.info("App," + level + "," + joinPoint.getSignature().getName() + ","
80 | + (t1 - t0) / 1000000.);
81 | level--;
82 | return result;
83 | }
84 |
85 | @Around("execution(* org.springframework.web.reactive.DispatcherHandler+.initStrategies(..))")
86 | public Object initStrategies(ProceedingJoinPoint joinPoint) throws Throwable {
87 | long t0 = System.nanoTime();
88 | Object result = joinPoint.proceed();
89 | long t1 = System.nanoTime();
90 | logger.info("Strategies,"
91 | + joinPoint.getSignature().getDeclaringType().getSimpleName() + "."
92 | + joinPoint.getSignature().getName() + "," + (t1 - t0) / 1000000.);
93 | return result;
94 | }
95 |
96 | @Around("execution(* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory+.initializeBean(String, Object, ..)) && args(name,bean,..)")
97 | public Object init(ProceedingJoinPoint joinPoint, String name, Object bean) throws Throwable {
98 | String task = init.currentTaskName();
99 | if (task != null) {
100 | init.stop();
101 | }
102 | init.start(name);
103 | int count0 = init.getTaskCount();
104 | long t0 = System.nanoTime();
105 | Object result = joinPoint.proceed();
106 | long t1 = System.nanoTime();
107 | int count1 = init.getTaskCount();
108 | init.stop();
109 | if (task != null) {
110 | init.start(task);
111 | }
112 | else {
113 | logger.info(
114 | "Init,," + bean.getClass().getName() + "," + (t1 - t0) / 1000000.);
115 | logger.info("Count,," + bean.getClass().getName() + "," + (count1 - count0));
116 | }
117 | return result;
118 | }
119 |
120 | @EventListener
121 | public void started(ContextRefreshedEvent event) {
122 | logger.debug("Total bind: " + bind.getTotalTimeMillis());
123 | logger.debug("Total init: " + init.getTotalTimeMillis());
124 | }
125 |
126 | }
--------------------------------------------------------------------------------
/timing/src/main/resources/META-INF/aop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/timing/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | org.springframework.boot.aspects.AspectConfiguration
--------------------------------------------------------------------------------
/timing/src/test/java/org/springframework/boot/aspects/DemoApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.boot.aspects;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class DemoApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(DemoApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/timing/src/test/java/org/springframework/boot/aspects/DemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.boot.aspects;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class DemoApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------