mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-18 18:22:23 +00:00
Compare commits
953
Commits
4.2.x
...
v4.3.2.RELEASE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62b8f97f0f | ||
|
|
ff878ea9dc | ||
|
|
7021a4be44 | ||
|
|
5c4737c3d0 | ||
|
|
fbf3807af1 | ||
|
|
703c37ec88 | ||
|
|
96440878bb | ||
|
|
b5c11ffb1c | ||
|
|
7f5b323d50 | ||
|
|
67176e2b75 | ||
|
|
79f3cf3263 | ||
|
|
9ee1dc79fd | ||
|
|
9e2c34dfa6 | ||
|
|
cc93c2a559 | ||
|
|
15c7044c4d | ||
|
|
0ef80d3579 | ||
|
|
95c2e0a996 | ||
|
|
da3e8611e1 | ||
|
|
64595597f3 | ||
|
|
82f2983cd4 | ||
|
|
9451177c35 | ||
|
|
9ed087d5da | ||
|
|
77f22e9674 | ||
|
|
8ccfdbbcf9 | ||
|
|
5a92aa4e06 | ||
|
|
7b1010cf61 | ||
|
|
45b2f5bac4 | ||
|
|
36e1c82ef5 | ||
|
|
503d65d570 | ||
|
|
fe17f8da41 | ||
|
|
b583aa1579 | ||
|
|
e0d81b97bb | ||
|
|
90752f9d87 | ||
|
|
3663aa675a | ||
|
|
1ca4b81856 | ||
|
|
4e7e06f549 | ||
|
|
b2f0bdb0f4 | ||
|
|
d98bd34200 | ||
|
|
940bdd878e | ||
|
|
df556333a8 | ||
|
|
116f05eda6 | ||
|
|
b187bbeca3 | ||
|
|
479a83b628 | ||
|
|
1c18100143 | ||
|
|
5d3c0f33f6 | ||
|
|
afe106e254 | ||
|
|
69dd40ec89 | ||
|
|
dee50d5e28 | ||
|
|
9e93403857 | ||
|
|
12bff6b3a0 | ||
|
|
70e666b4a3 | ||
|
|
29f980ec72 | ||
|
|
1d39d762f0 | ||
|
|
4d6d5e0ddd | ||
|
|
4ea5f070a4 | ||
|
|
da59b4da9b | ||
|
|
0065a160cc | ||
|
|
52f46c7fea | ||
|
|
f0a826ec0c | ||
|
|
5c3c0f73c1 | ||
|
|
be0b71ce31 | ||
|
|
f85d48dd31 | ||
|
|
a1b58ee601 | ||
|
|
e30429051d | ||
|
|
942ead75e2 | ||
|
|
453688f6df | ||
|
|
7d7a161102 | ||
|
|
aaa223ae66 | ||
|
|
d11c624fb0 | ||
|
|
275e51b19d | ||
|
|
ab62edeeaa | ||
|
|
813108a928 | ||
|
|
3c14911401 | ||
|
|
4337f14627 | ||
|
|
92d78c10a2 | ||
|
|
16d5ba9b3a | ||
|
|
52065a736b | ||
|
|
11cb109114 | ||
|
|
d7eadd41d6 | ||
|
|
080dcad218 | ||
|
|
a6e4b64c23 | ||
|
|
f6334fc62b | ||
|
|
c6752e6023 | ||
|
|
b204437cef | ||
|
|
e5122d084a | ||
|
|
e7a53e37fb | ||
|
|
e5de7d5455 | ||
|
|
cfc560c4c4 | ||
|
|
498d896ef0 | ||
|
|
037746da44 | ||
|
|
d7184d1ad8 | ||
|
|
1c73664c40 | ||
|
|
8389e3fc35 | ||
|
|
a530a1c7f2 | ||
|
|
716273df47 | ||
|
|
49d78b4835 | ||
|
|
cac58738c9 | ||
|
|
66fd86be33 | ||
|
|
d9993243b6 | ||
|
|
d35709dfbc | ||
|
|
2b822d5053 | ||
|
|
60123b6ca3 | ||
|
|
5c6f57ba78 | ||
|
|
dda0942c78 | ||
|
|
66ec1c1618 | ||
|
|
9c29ed75f8 | ||
|
|
16949941f8 | ||
|
|
232cfe5e98 | ||
|
|
c4c941c43f | ||
|
|
89396ff01f | ||
|
|
eba873067c | ||
|
|
2d5496df2b | ||
|
|
f2328e8e3c | ||
|
|
1d42009c0a | ||
|
|
37e42e68e8 | ||
|
|
772bc030ee | ||
|
|
6cd85ddde7 | ||
|
|
775ffbe10b | ||
|
|
1a7c6d3b10 | ||
|
|
db963bc556 | ||
|
|
64628dc8cb | ||
|
|
52387cac9a | ||
|
|
5657283071 | ||
|
|
ebdc770ed3 | ||
|
|
2cdcf752ba | ||
|
|
e38623df87 | ||
|
|
a30ab30e4e | ||
|
|
a25c43f695 | ||
|
|
15c96b8efd | ||
|
|
ea5baeb05a | ||
|
|
e15f7efff8 | ||
|
|
4102c62734 | ||
|
|
351a729317 | ||
|
|
711eb99812 | ||
|
|
5e08598a2a | ||
|
|
f5282bc1e3 | ||
|
|
0345d734e6 | ||
|
|
3dbf25e018 | ||
|
|
f7dd757593 | ||
|
|
7f16bdaf74 | ||
|
|
fd9d518c36 | ||
|
|
a2aa82eb31 | ||
|
|
981d4494c6 | ||
|
|
0de85e3a73 | ||
|
|
058279bc7e | ||
|
|
db1092f119 | ||
|
|
848562d68a | ||
|
|
56db1af11d | ||
|
|
8cb9d5ebae | ||
|
|
01f115869b | ||
|
|
f9fec73f1d | ||
|
|
ba885f3d0b | ||
|
|
919f6c96f9 | ||
|
|
981a748dcc | ||
|
|
6f9fb31bf9 | ||
|
|
c145ceebf3 | ||
|
|
bcfc09a93c | ||
|
|
b92576d8d9 | ||
|
|
d41178c75a | ||
|
|
9656015d26 | ||
|
|
7d39957ec9 | ||
|
|
9001af7efb | ||
|
|
b5364d5f1a | ||
|
|
dcb2c73102 | ||
|
|
045ee52232 | ||
|
|
2fd4462268 | ||
|
|
0815560c85 | ||
|
|
d60028caf1 | ||
|
|
ca12e13ef8 | ||
|
|
57ca8f5347 | ||
|
|
7c96059ca3 | ||
|
|
f0451294de | ||
|
|
53909a5333 | ||
|
|
1dfc0ffd43 | ||
|
|
d51c22a789 | ||
|
|
8432c62b50 | ||
|
|
f7dd8e34b3 | ||
|
|
4465e4ff6c | ||
|
|
c6f63bdb30 | ||
|
|
d1d29cf699 | ||
|
|
a211d1472e | ||
|
|
da051b87e6 | ||
|
|
c9de6f23ef | ||
|
|
cc7781ecf3 | ||
|
|
8fc84e2d6f | ||
|
|
981c894acf | ||
|
|
99ae7e3bcb | ||
|
|
47d77252d3 | ||
|
|
6804aad06f | ||
|
|
e2810904b0 | ||
|
|
f5a9d5e076 | ||
|
|
01d234f9f3 | ||
|
|
c121f460b1 | ||
|
|
31aed61d15 | ||
|
|
4432da3659 | ||
|
|
de78f05707 | ||
|
|
eaa9511921 | ||
|
|
5a0100111e | ||
|
|
8c4bc3656b | ||
|
|
6807bcb863 | ||
|
|
c412eabb00 | ||
|
|
abcfffdde9 | ||
|
|
3c987b179d | ||
|
|
c19740a020 | ||
|
|
c2a50ad1bf | ||
|
|
9131ebbea6 | ||
|
|
e7561b1d7c | ||
|
|
998b83ce8c | ||
|
|
d7320f41c0 | ||
|
|
a9fda3e7e2 | ||
|
|
f657952cee | ||
|
|
9394616f8f | ||
|
|
521c41d75e | ||
|
|
ae11387b4a | ||
|
|
7de61f80a7 | ||
|
|
ca9ffa2012 | ||
|
|
ea728b15c8 | ||
|
|
c74d979735 | ||
|
|
b7f589547d | ||
|
|
1f3ac340fa | ||
|
|
7ee687c798 | ||
|
|
9975f02e4d | ||
|
|
5a81727180 | ||
|
|
39f143563d | ||
|
|
37de0e45f6 | ||
|
|
e4976a2c6d | ||
|
|
fc40643033 | ||
|
|
27215b5061 | ||
|
|
8343ce9e44 | ||
|
|
e2fa282e14 | ||
|
|
d10134b5a5 | ||
|
|
54f84cbd97 | ||
|
|
92f1b69e8c | ||
|
|
22c260f3fe | ||
|
|
f20f6c952a | ||
|
|
431a50823f | ||
|
|
7e95cd8b4e | ||
|
|
71463fb399 | ||
|
|
9064d38e4c | ||
|
|
bff8259fb0 | ||
|
|
3576ff051c | ||
|
|
24f5f368b0 | ||
|
|
822e40e24f | ||
|
|
86557f25af | ||
|
|
cf0a0cd5d8 | ||
|
|
a1e9459a43 | ||
|
|
d6284202f1 | ||
|
|
250d82768f | ||
|
|
6efa058917 | ||
|
|
f7f2327f60 | ||
|
|
98eaf05c8f | ||
|
|
42bf007604 | ||
|
|
03affa02db | ||
|
|
2d85accb83 | ||
|
|
31a93792b2 | ||
|
|
49bc2a9a02 | ||
|
|
917948deac | ||
|
|
abfe3f209d | ||
|
|
a979885d17 | ||
|
|
dacc31e3d3 | ||
|
|
65f6ea320a | ||
|
|
4e8754ea87 | ||
|
|
f4ab6d8d52 | ||
|
|
a1851845ad | ||
|
|
06e3ee6820 | ||
|
|
aa3b04c937 | ||
|
|
ace624a01a | ||
|
|
7d4d3db0dd | ||
|
|
c2625f968c | ||
|
|
400206a2fe | ||
|
|
a9217d51c2 | ||
|
|
9c02a99d38 | ||
|
|
3fb58cda8e | ||
|
|
1e003a1c90 | ||
|
|
4a81aaba6c | ||
|
|
8c79f23175 | ||
|
|
d651ebfd2d | ||
|
|
c15f27cfa8 | ||
|
|
66bab2a9fc | ||
|
|
5682950289 | ||
|
|
42d32ba396 | ||
|
|
e5dbe12e85 | ||
|
|
1b1aac9172 | ||
|
|
5400bb9110 | ||
|
|
7dc181261e | ||
|
|
2367f52aaf | ||
|
|
a1a87679da | ||
|
|
a31f0bb3c0 | ||
|
|
3c92ddc94b | ||
|
|
3f85efe107 | ||
|
|
08ddd1b3bc | ||
|
|
8c139ef444 | ||
|
|
ab478d14fa | ||
|
|
162aedccbe | ||
|
|
f09c7868d8 | ||
|
|
e6e3ca3e96 | ||
|
|
e26478e3de | ||
|
|
7b13311f03 | ||
|
|
6b3eba0500 | ||
|
|
64c388d524 | ||
|
|
0f6711fe3b | ||
|
|
7ce5ba4a3f | ||
|
|
3433fe35df | ||
|
|
52e5b4a6ff | ||
|
|
76964e16ef | ||
|
|
46e41a9d94 | ||
|
|
05b29a4a17 | ||
|
|
76ee46847a | ||
|
|
1be544f8fa | ||
|
|
5ac31fb39d | ||
|
|
7737c3c7e5 | ||
|
|
cbc46760b7 | ||
|
|
07ea3745c4 | ||
|
|
09b45d2c0f | ||
|
|
f83cbff543 | ||
|
|
e45d33f9de | ||
|
|
29da44c8dc | ||
|
|
fdb31cd715 | ||
|
|
bd40a93604 | ||
|
|
240f254bfc | ||
|
|
220711d45b | ||
|
|
977840884b | ||
|
|
55dae618a6 | ||
|
|
15138ed96f | ||
|
|
9412f7a094 | ||
|
|
777767c7ee | ||
|
|
8d36332268 | ||
|
|
cd6b203c88 | ||
|
|
8ddb432694 | ||
|
|
e0734aede8 | ||
|
|
6ab8d36ed0 | ||
|
|
b331ad5b2a | ||
|
|
ce2f28da49 | ||
|
|
335d968f85 | ||
|
|
a50ea80e4e | ||
|
|
1838d7e97f | ||
|
|
8f0f5faf4d | ||
|
|
d06188ed4d | ||
|
|
e5d52a96a7 | ||
|
|
9798912557 | ||
|
|
06b2d2b89e | ||
|
|
538c582342 | ||
|
|
bb1a0311d8 | ||
|
|
87b93a7ae9 | ||
|
|
65a8f5ed64 | ||
|
|
f73df2e138 | ||
|
|
bf7b475267 | ||
|
|
9bf5a5cbcb | ||
|
|
9ec0873604 | ||
|
|
b2c9c8abcf | ||
|
|
c84c1cfd1b | ||
|
|
67a9f40c95 | ||
|
|
4a4cd5bde8 | ||
|
|
151530b93b | ||
|
|
31d634e6bf | ||
|
|
920eba79f8 | ||
|
|
065b7968a3 | ||
|
|
0d007a328b | ||
|
|
5ec6206e3f | ||
|
|
6e4e52b23a | ||
|
|
fee2533825 | ||
|
|
44e652f99e | ||
|
|
50c11028d5 | ||
|
|
aafd46aeb3 | ||
|
|
28f2f4a431 | ||
|
|
f8720e256d | ||
|
|
7cdcc102a9 | ||
|
|
ff38224da6 | ||
|
|
b1bc920e72 | ||
|
|
c402932ba1 | ||
|
|
368f29d5bc | ||
|
|
e38bfb1a68 | ||
|
|
970dc4ae11 | ||
|
|
6489a7670c | ||
|
|
87ed8e939c | ||
|
|
64d4e91b6e | ||
|
|
bee1b77af5 | ||
|
|
44a9c495ab | ||
|
|
b28d96af7d | ||
|
|
999112216d | ||
|
|
3b44c47dcd | ||
|
|
f1cb793ccb | ||
|
|
977734cc59 | ||
|
|
62ce9afe3a | ||
|
|
5f4e838f41 | ||
|
|
7e55b0822f | ||
|
|
3222664024 | ||
|
|
96875fe015 | ||
|
|
570851e8e4 | ||
|
|
e3667467f6 | ||
|
|
ee31617ebe | ||
|
|
dcfa4740ee | ||
|
|
88b5b12baf | ||
|
|
da112611a5 | ||
|
|
836a321ab2 | ||
|
|
74608e6b49 | ||
|
|
831f09cf48 | ||
|
|
10554a85c9 | ||
|
|
454165f4c8 | ||
|
|
741fbcd6fe | ||
|
|
1e7be7be3f | ||
|
|
f4b7da9a3e | ||
|
|
7d7d1c365a | ||
|
|
82778e1746 | ||
|
|
bdb94738ec | ||
|
|
b6f1afd471 | ||
|
|
537193a4e0 | ||
|
|
d695f65e7c | ||
|
|
550a3209f7 | ||
|
|
b82df144e4 | ||
|
|
448621ac58 | ||
|
|
437ffa6067 | ||
|
|
21e4ac1aa2 | ||
|
|
4407bd794d | ||
|
|
dc7ec44188 | ||
|
|
cb9549655c | ||
|
|
572e535fba | ||
|
|
4ae065996b | ||
|
|
3abe75b254 | ||
|
|
f3b09464f3 | ||
|
|
e365ffb67a | ||
|
|
37bd51cf6d | ||
|
|
463c8f149d | ||
|
|
157dcab56c | ||
|
|
5c1d3fca15 | ||
|
|
042d8d0b4c | ||
|
|
ed14ae60e5 | ||
|
|
4ea4257e3c | ||
|
|
8213df817e | ||
|
|
ebeba43830 | ||
|
|
5bd5c74e7c | ||
|
|
b6f99e38ae | ||
|
|
0c0c904837 | ||
|
|
f752e050bc | ||
|
|
6d7f497ab3 | ||
|
|
5a0a88c039 | ||
|
|
a9aa85c6c0 | ||
|
|
4024b2fd4b | ||
|
|
6db6f23a04 | ||
|
|
6573e9142c | ||
|
|
797f5dbba6 | ||
|
|
7c450fad3b | ||
|
|
d2d528dc05 | ||
|
|
cfdb683449 | ||
|
|
6c0cae87b4 | ||
|
|
e18d5b591a | ||
|
|
26378cd604 | ||
|
|
d554229981 | ||
|
|
996c1cc0a6 | ||
|
|
ad7285df0b | ||
|
|
1bccc8f1cd | ||
|
|
1f9a9cf404 | ||
|
|
edea66a967 | ||
|
|
8bfba6a07a | ||
|
|
13f889e914 | ||
|
|
696dcb72a5 | ||
|
|
739ae8c045 | ||
|
|
6826bdd111 | ||
|
|
f6cb30b165 | ||
|
|
14bf6509ec | ||
|
|
5619b005f0 | ||
|
|
b7819e6ec8 | ||
|
|
ea09e578b9 | ||
|
|
2ed3382a60 | ||
|
|
f35ec5353a | ||
|
|
d40d2ffe5e | ||
|
|
3597879608 | ||
|
|
eec22f5072 | ||
|
|
b947bfe8e9 | ||
|
|
3910350b0a | ||
|
|
6298292523 | ||
|
|
2dae4d8134 | ||
|
|
26bbb6e767 | ||
|
|
b2a17ba537 | ||
|
|
4fa11e334f | ||
|
|
54aeb7a5d6 | ||
|
|
a8b5ea1c51 | ||
|
|
4742aa0bfe | ||
|
|
2353f39ee4 | ||
|
|
4836d06704 | ||
|
|
c6ff0951fc | ||
|
|
94cb7786c8 | ||
|
|
862d10c128 | ||
|
|
b0c6357540 | ||
|
|
fc839331a7 | ||
|
|
fee056a1b1 | ||
|
|
c6f6e192c0 | ||
|
|
d572b022cc | ||
|
|
c6b1f38651 | ||
|
|
b6d9fd39e6 | ||
|
|
6b7731cc89 | ||
|
|
775bcccd10 | ||
|
|
852212d0c5 | ||
|
|
46e0484bf8 | ||
|
|
8d0083ca96 | ||
|
|
517ebd1d3e | ||
|
|
2cdb0cf690 | ||
|
|
06db5aa43f | ||
|
|
9a52c81443 | ||
|
|
abe7345008 | ||
|
|
55f1c98c39 | ||
|
|
1ec35e9c62 | ||
|
|
3eff478c45 | ||
|
|
86d5c5c0f7 | ||
|
|
7e4563a825 | ||
|
|
2453edbb10 | ||
|
|
38714b35e7 | ||
|
|
20bb25647f | ||
|
|
2535469099 | ||
|
|
63115ed6eb | ||
|
|
c5b318a4cc | ||
|
|
9af12d290e | ||
|
|
5025c615b1 | ||
|
|
311d4c95a3 | ||
|
|
3c18a4533a | ||
|
|
e079a726f8 | ||
|
|
c7bd3b8440 | ||
|
|
15fe8279e6 | ||
|
|
9b2023111d | ||
|
|
7a5e93ff16 | ||
|
|
6bfe0c050d | ||
|
|
59c88eb3c0 | ||
|
|
2a715e9c61 | ||
|
|
532ed0a4cf | ||
|
|
a5139f3c66 | ||
|
|
799736c571 | ||
|
|
f1378aa376 | ||
|
|
744350a262 | ||
|
|
d22480b0eb | ||
|
|
4cd7ba12bb | ||
|
|
5f6406430f | ||
|
|
a1a06cd665 | ||
|
|
5045579028 | ||
|
|
a905412514 | ||
|
|
6e3fac85f3 | ||
|
|
9ac9135c24 | ||
|
|
c5200978b0 | ||
|
|
11221f5ccb | ||
|
|
411ff8450f | ||
|
|
e2ba477405 | ||
|
|
1ca4340271 | ||
|
|
431ca9314a | ||
|
|
455bf45fa4 | ||
|
|
160410c148 | ||
|
|
7ae44c2565 | ||
|
|
4a6c2dbb15 | ||
|
|
d3822c8d19 | ||
|
|
7d96ad1f6e | ||
|
|
8246fe4534 | ||
|
|
ec7c3aa349 | ||
|
|
a95bf6e0fc | ||
|
|
2153d88706 | ||
|
|
43661ededb | ||
|
|
856da8e395 | ||
|
|
7a3bc2e473 | ||
|
|
f5a5a81e95 | ||
|
|
92dd4eb3ef | ||
|
|
9439a008d7 | ||
|
|
d9025ddaa7 | ||
|
|
7beff7b40a | ||
|
|
b1ca18e0dc | ||
|
|
2d565c7944 | ||
|
|
7c7e7865bf | ||
|
|
8d3ec50e87 | ||
|
|
d2c0885e29 | ||
|
|
35eb52e558 | ||
|
|
b1121fba70 | ||
|
|
30d457c622 | ||
|
|
1c3c88f81e | ||
|
|
f422e490b0 | ||
|
|
1a302e1fac | ||
|
|
183594207f | ||
|
|
e904ce4ead | ||
|
|
e83e3ec9de | ||
|
|
dfd4aae4f6 | ||
|
|
2a9b2ca5fd | ||
|
|
33a4e9e57f | ||
|
|
582864802e | ||
|
|
971ccab038 | ||
|
|
2152f436f9 | ||
|
|
c41c5dd5c9 | ||
|
|
92e715ed93 | ||
|
|
f2f87ff1e0 | ||
|
|
155fa3754b | ||
|
|
094cf6cafb | ||
|
|
beb01e674e | ||
|
|
cbd1342fbb | ||
|
|
87a3a5cb3b | ||
|
|
406d06118d | ||
|
|
71294df238 | ||
|
|
d124a13eb4 | ||
|
|
8852a5e178 | ||
|
|
b4de66ff9a | ||
|
|
0b1639d963 | ||
|
|
100f3c5eeb | ||
|
|
0597ff109e | ||
|
|
b944283354 | ||
|
|
b6f69492a3 | ||
|
|
68f6cf9d3a | ||
|
|
6aa216afb6 | ||
|
|
8222ff465d | ||
|
|
51eccf552f | ||
|
|
bb590db396 | ||
|
|
8ca6a18dae | ||
|
|
8e24a4153c | ||
|
|
ed341695a8 | ||
|
|
71cf7b4053 | ||
|
|
2244461778 | ||
|
|
0a56667093 | ||
|
|
89cf4772d5 | ||
|
|
e85a06234b | ||
|
|
93fb7be783 | ||
|
|
504779e210 | ||
|
|
0d12b84022 | ||
|
|
4bead6e542 | ||
|
|
cbcc9998f1 | ||
|
|
bea26413b4 | ||
|
|
78690a24fb | ||
|
|
ca8acc8758 | ||
|
|
eb654dc177 | ||
|
|
e086a5d58b | ||
|
|
1772278053 | ||
|
|
9d4c6e4d06 | ||
|
|
dfa1938ac1 | ||
|
|
ff2a911baa | ||
|
|
f162256906 | ||
|
|
1a76f7e9c2 | ||
|
|
5067f00228 | ||
|
|
41da04d386 | ||
|
|
9e167045fc | ||
|
|
6f2c968925 | ||
|
|
e98738d8ba | ||
|
|
44c32128dc | ||
|
|
36e2dd90a7 | ||
|
|
6fcc869338 | ||
|
|
067994712d | ||
|
|
50bcd67fb6 | ||
|
|
18e9699a2b | ||
|
|
4cf0b59e00 | ||
|
|
7b861c9a8a | ||
|
|
ffbf264976 | ||
|
|
b3b3fc5a7e | ||
|
|
3df66d023c | ||
|
|
0d6f80052d | ||
|
|
b3abd3b809 | ||
|
|
c385427397 | ||
|
|
61824b1ade | ||
|
|
2bb2657483 | ||
|
|
467b5f3f28 | ||
|
|
5923ee8af3 | ||
|
|
161ec15a46 | ||
|
|
b423596b2e | ||
|
|
df7b24b8e7 | ||
|
|
197434b3ec | ||
|
|
816185233d | ||
|
|
a02fd7c995 | ||
|
|
9c0f99c0b5 | ||
|
|
8e5e384de7 | ||
|
|
1815a6a7eb | ||
|
|
a2bfe86630 | ||
|
|
31e0386bcb | ||
|
|
9d3dd1bc13 | ||
|
|
0c66838268 | ||
|
|
6fcb6630d7 | ||
|
|
ab16053ed4 | ||
|
|
8a83af55b8 | ||
|
|
7a32ce317c | ||
|
|
b6dd8a9233 | ||
|
|
4c964473b1 | ||
|
|
1bc1df2d0f | ||
|
|
ca19920d74 | ||
|
|
a68b910b7c | ||
|
|
46189b48fc | ||
|
|
91872b0d74 | ||
|
|
08a08725be | ||
|
|
a56c69c9ca | ||
|
|
f58ef24efd | ||
|
|
37a3fa96d1 | ||
|
|
3329abffc8 | ||
|
|
7b1fcfc7c3 | ||
|
|
028a690100 | ||
|
|
ed98393fb2 | ||
|
|
1899fb37c1 | ||
|
|
a3789120c9 | ||
|
|
8ff9e818a5 | ||
|
|
b9fe6d89da | ||
|
|
d8a05592e2 | ||
|
|
2ca11029f2 | ||
|
|
f4cbd98459 | ||
|
|
b3d67b928b | ||
|
|
a94ffbb17a | ||
|
|
963fea0e3f | ||
|
|
e98977cbc8 | ||
|
|
f32aded27a | ||
|
|
26575148a5 | ||
|
|
700ab2fc98 | ||
|
|
a7ad49adcf | ||
|
|
890819f886 | ||
|
|
5ed9046886 | ||
|
|
d6700b7a10 | ||
|
|
65d144b1e5 | ||
|
|
f33578ef0f | ||
|
|
c4117885bd | ||
|
|
48ee9b52d4 | ||
|
|
18a59dad52 | ||
|
|
416966d943 | ||
|
|
ec3571fd4d | ||
|
|
1b53edfc5e | ||
|
|
0adc4921ed | ||
|
|
08eb623c41 | ||
|
|
1c2ac49f2a | ||
|
|
923534595c | ||
|
|
8495fcf109 | ||
|
|
7fcb277de9 | ||
|
|
ea4a766df7 | ||
|
|
e0d7c6be00 | ||
|
|
c2f704717e | ||
|
|
25be5e060c | ||
|
|
ac44f9edd9 | ||
|
|
ac3847bf4a | ||
|
|
513c1ea3d9 | ||
|
|
43d72871bd | ||
|
|
024bd6e604 | ||
|
|
57b466fdfc | ||
|
|
a6d31d5212 | ||
|
|
37b3b24578 | ||
|
|
c73e52412a | ||
|
|
7dac2e3256 | ||
|
|
6ce76314e7 | ||
|
|
5c87afc51d | ||
|
|
1253b451f5 | ||
|
|
51c35bf81c | ||
|
|
a9d62372bf | ||
|
|
5e5bf7f518 | ||
|
|
e36b7531d8 | ||
|
|
37b32d38bc | ||
|
|
343bb2f130 | ||
|
|
b79e8a5cbc | ||
|
|
268ebd7e89 | ||
|
|
8cb35197ef | ||
|
|
0dff782402 | ||
|
|
f6ebc4ce97 | ||
|
|
27c1280949 | ||
|
|
37de0b241d | ||
|
|
a1e9e6f53e | ||
|
|
d53c04b4df | ||
|
|
c45ad3022b | ||
|
|
aba04d576f | ||
|
|
8558cbc9bf | ||
|
|
b11d345c0d | ||
|
|
901c2d5f74 | ||
|
|
f61b998447 | ||
|
|
c788a8a260 | ||
|
|
0ab3f6092c | ||
|
|
a4a3cda29f | ||
|
|
e77ff3c991 | ||
|
|
cdfcc23b6f | ||
|
|
29cd1808b7 | ||
|
|
43bcab9c1a | ||
|
|
903ae48382 | ||
|
|
449f704650 | ||
|
|
afe7bf2695 | ||
|
|
e4539d9f40 | ||
|
|
7756feacd8 | ||
|
|
1291d6e1bd | ||
|
|
902a7287f7 | ||
|
|
09a40b8a08 | ||
|
|
7ed2b8fd81 | ||
|
|
26edc674ed | ||
|
|
b49235ac59 | ||
|
|
e90310612f | ||
|
|
f108deb114 | ||
|
|
28e8af2e2e | ||
|
|
81f68463ec | ||
|
|
677a321571 | ||
|
|
6d2b9a0136 | ||
|
|
d6648a06c9 | ||
|
|
e81c7dfc4c | ||
|
|
03e3ef53ab | ||
|
|
bedf1a9bd0 | ||
|
|
f5aa011722 | ||
|
|
aa064d7653 | ||
|
|
1cf0fb8174 | ||
|
|
ea46ad8022 | ||
|
|
3cf5cfd672 | ||
|
|
468f083ab0 | ||
|
|
d157ce598b | ||
|
|
aed56ea732 | ||
|
|
ccbfd44862 | ||
|
|
0ecede028c | ||
|
|
2e7470b27f | ||
|
|
806e79b14b | ||
|
|
e62ada898b | ||
|
|
698f923fc3 | ||
|
|
7df3a327f6 | ||
|
|
3779fe9bf6 | ||
|
|
b4f33adf48 | ||
|
|
a3a5a03ee3 | ||
|
|
2607a22537 | ||
|
|
319e8e2c2f | ||
|
|
4a0fa69ce4 | ||
|
|
64e77de23b | ||
|
|
64ce8a81c3 | ||
|
|
8a69159004 | ||
|
|
d18b3f049a | ||
|
|
c95dfca726 | ||
|
|
837cb752a4 | ||
|
|
ebad8db8d5 | ||
|
|
64d83e78ea | ||
|
|
e14f42f386 | ||
|
|
135738f9bf | ||
|
|
a730e55d92 | ||
|
|
ccd17dfaea | ||
|
|
d70ad765bf | ||
|
|
fb7dfc4569 | ||
|
|
2b3ad218e5 | ||
|
|
84fe46cd43 | ||
|
|
8f1d06f19c | ||
|
|
ebccfd023a | ||
|
|
9cc518d167 | ||
|
|
cd903e26de | ||
|
|
a12f23936c | ||
|
|
415b2763ce | ||
|
|
6a9455b7d0 | ||
|
|
1416c2a00e | ||
|
|
2f6d86b7aa | ||
|
|
952a3170e6 | ||
|
|
ae224bed3e | ||
|
|
18db77da7c | ||
|
|
df223eb118 | ||
|
|
3554348919 | ||
|
|
9e16cbda4c | ||
|
|
5185953f29 | ||
|
|
a5f4aa6824 | ||
|
|
29700658d4 | ||
|
|
0d04af14f8 | ||
|
|
9b9df6a744 | ||
|
|
714ae2684c | ||
|
|
eb49f3c225 | ||
|
|
a112557dc4 | ||
|
|
73a794336c | ||
|
|
4b1183582a | ||
|
|
1320da906b | ||
|
|
74c07d3085 | ||
|
|
182b1e99e3 | ||
|
|
dc8de51408 | ||
|
|
cdc9bf76a9 | ||
|
|
9761af9ad8 | ||
|
|
c1352c1201 | ||
|
|
2fc2c29e9a | ||
|
|
3dae3fd8a9 | ||
|
|
037f351efd | ||
|
|
93298fc9fa | ||
|
|
4818378c25 | ||
|
|
7690f27c5e | ||
|
|
f3c2bb6557 | ||
|
|
24fdf64d91 | ||
|
|
e56587dcc3 | ||
|
|
31a3607de6 | ||
|
|
50829c9fdc | ||
|
|
773d175681 | ||
|
|
e14c2de1d2 | ||
|
|
5d4547d343 | ||
|
|
96cb0e6bd6 | ||
|
|
ee946f6ac6 | ||
|
|
554bf4958d | ||
|
|
cdda839426 | ||
|
|
6c282096c6 | ||
|
|
d681f77d62 | ||
|
|
473cf9c40e | ||
|
|
6e7e4c0359 | ||
|
|
fca7c52236 | ||
|
|
04f31816bd | ||
|
|
9bffb9e53f | ||
|
|
9152f20bc1 | ||
|
|
8968f09c59 | ||
|
|
27c2e8c80d | ||
|
|
388bd87ef0 | ||
|
|
aecb8b6c6b | ||
|
|
74d3bceb19 | ||
|
|
9e4cf85af7 | ||
|
|
4f955932a7 | ||
|
|
3242ad8fc4 | ||
|
|
e48ec4fcd3 | ||
|
|
1d8a3e1f07 | ||
|
|
7d0ebddebe | ||
|
|
826a00a56a | ||
|
|
d1551bdcec | ||
|
|
470ea977e1 | ||
|
|
63958ac0ff | ||
|
|
873b173dcc | ||
|
|
1cfeb07fa5 | ||
|
|
bc671f05d6 | ||
|
|
258cc7b27f | ||
|
|
12969f6268 | ||
|
|
74b77e0d74 | ||
|
|
12b73caa84 | ||
|
|
8656186f60 | ||
|
|
4adb7e2500 | ||
|
|
bb0bc3d415 | ||
|
|
95d62658ff | ||
|
|
07fd7b905e | ||
|
|
0194988425 | ||
|
|
cf20308134 | ||
|
|
41ee25b1e7 | ||
|
|
66dd880335 | ||
|
|
d444ef4871 | ||
|
|
9b5e47026c | ||
|
|
1ce9788a66 | ||
|
|
bb3ff25cad | ||
|
|
57b3ee324f | ||
|
|
dd930b3b66 | ||
|
|
f8860e2938 | ||
|
|
4668aa775d | ||
|
|
b28310d0b9 | ||
|
|
0dd320f92e | ||
|
|
cad2ce0ac2 | ||
|
|
09cea6e6bb | ||
|
|
d59b0d12d4 | ||
|
|
adf744cce0 | ||
|
|
1fc3fc8bf7 | ||
|
|
edd8e2d56d | ||
|
|
19d97c4253 | ||
|
|
15c7dcd11a | ||
|
|
66562f2589 | ||
|
|
db1171d5c4 | ||
|
|
64bd8b7f34 | ||
|
|
387c8a8181 | ||
|
|
06056e6aa6 | ||
|
|
2e6eb614b5 | ||
|
|
fca5365cf1 | ||
|
|
1502e49fa5 | ||
|
|
3a238a2b61 | ||
|
|
13aabeef37 | ||
|
|
967ef73765 | ||
|
|
9e7c791a0f | ||
|
|
3d87718fc6 | ||
|
|
08748ecaa4 | ||
|
|
2cfe00ce32 | ||
|
|
0084c077bb | ||
|
|
760668c034 | ||
|
|
5b3edcd9f9 | ||
|
|
0e68d2e951 | ||
|
|
9eb713ae2c | ||
|
|
b75f5faf88 | ||
|
|
e90942223f | ||
|
|
a2a9c47e59 | ||
|
|
8ce5e88c66 | ||
|
|
db05f43a75 | ||
|
|
2fd48c92d7 | ||
|
|
93de3553c1 | ||
|
|
752d3c715a | ||
|
|
07022eae1e |
@@ -0,0 +1,44 @@
|
||||
= Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open
|
||||
and welcoming community, we pledge to respect all people who contribute through reporting
|
||||
issues, posting feature requests, updating documentation, submitting pull requests or
|
||||
patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for
|
||||
everyone, regardless of level of experience, gender, gender identity and expression,
|
||||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses,
|
||||
without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this
|
||||
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
|
||||
that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
|
||||
consistently applying these principles to every aspect of managing this project. Project
|
||||
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
|
||||
from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an
|
||||
individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
|
||||
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
|
||||
be reviewed and investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
|
||||
with regard to the reporter of an incident.
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
|
||||
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
|
||||
+4
-8
@@ -6,6 +6,10 @@ to expect from the Spring team when evaluating your submission._
|
||||
_Please refer back to this document as a checklist before issuing any pull
|
||||
request; this will save time for everyone!_
|
||||
|
||||
## Code of Conduct
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.adoc).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Take Your First Steps
|
||||
|
||||
### Understand the basics
|
||||
@@ -29,14 +33,6 @@ do not find something similar, please create a new JIRA issue before submitting
|
||||
a pull request unless the change is truly trivial -- for example: typo fixes,
|
||||
removing compiler warnings, etc.
|
||||
|
||||
### Discuss non-trivial contribution ideas with committers
|
||||
|
||||
If you're considering anything more than correcting a typo or fixing a minor
|
||||
bug, please discuss it on the [spring-framework-contrib][] mailing list before
|
||||
submitting a pull request. We're happy to provide guidance, but please spend an
|
||||
hour or two researching the subject on your own, including searching the mailing
|
||||
list for prior discussions.
|
||||
|
||||
### Sign the Individual Contributor License Agreement (ICLA)
|
||||
|
||||
If you have not previously done so, please fill out and submit the
|
||||
|
||||
@@ -10,6 +10,10 @@ The framework also serves as the foundation for [Spring Integration][], [Spring
|
||||
and the rest of the Spring [family of projects][]. Browse the repositories under
|
||||
the [Spring organization][] on GitHub for a full list.
|
||||
|
||||
## Code of Conduct
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.adoc).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Downloading Artifacts
|
||||
See [downloading Spring artifacts][] for Maven repository information. Unable to
|
||||
use Maven or other transitive dependency management tools?
|
||||
|
||||
+143
-166
@@ -10,6 +10,10 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.sonarqube" version "1.1"
|
||||
}
|
||||
|
||||
ext {
|
||||
linkHomepage = 'https://projects.spring.io/spring-framework'
|
||||
linkCi = 'https://build.spring.io/browse/SPR'
|
||||
@@ -27,57 +31,54 @@ configure(allprojects) { project ->
|
||||
group = "org.springframework"
|
||||
version = qualifyVersionIfNecessary(version)
|
||||
|
||||
ext.aspectjVersion = "1.8.7"
|
||||
ext.aspectjVersion = "1.8.9"
|
||||
ext.caffeineVersion = "2.3.1"
|
||||
ext.eclipselinkVersion = "2.4.2"
|
||||
ext.ehcacheVersion = "2.10.1"
|
||||
ext.ehcacheVersion = "2.10.2"
|
||||
ext.ehcachejcacheVersion = "1.0.1"
|
||||
ext.ehcache3Version = "3.0.0.m4"
|
||||
ext.ejbApiVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.1"
|
||||
ext.ehcache3Version = "3.1.1"
|
||||
ext.ejbVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.2"
|
||||
ext.freemarkerVersion = "2.3.23"
|
||||
ext.groovyVersion = "2.4.5"
|
||||
ext.gsonVersion = "2.5"
|
||||
ext.groovyVersion = "2.4.7"
|
||||
ext.gsonVersion = "2.7"
|
||||
ext.guavaVersion = "19.0"
|
||||
ext.hamcrestVersion = "1.3"
|
||||
ext.hibernate3Version = "3.6.10.Final"
|
||||
ext.hibernate4Version = "4.3.11.Final"
|
||||
ext.hibernate5Version = "5.0.5.Final"
|
||||
ext.hibernate5Version = "5.2.1.Final"
|
||||
ext.hibval4Version = "4.3.2.Final"
|
||||
ext.hibval5Version = "5.2.2.Final"
|
||||
ext.hsqldbVersion = "2.3.3"
|
||||
ext.htmlunitVersion = "2.19"
|
||||
ext.httpasyncVersion = "4.1.1"
|
||||
ext.httpclientVersion = "4.5.1"
|
||||
ext.jackson2Version = "2.6.4"
|
||||
ext.jasperreportsVersion = "6.2.0"
|
||||
ext.javamailVersion = "1.5.4"
|
||||
ext.jettyVersion = "9.3.6.v20151106"
|
||||
ext.jodaVersion = "2.9.1"
|
||||
ext.jrubyVersion = "1.7.23" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jsonassertVersion = "1.2.3"
|
||||
ext.jsonpathVersion = "2.1.0"
|
||||
ext.hibval5Version = "5.2.4.Final"
|
||||
ext.hsqldbVersion = "2.3.4"
|
||||
ext.httpasyncVersion = "4.1.2"
|
||||
ext.httpclientVersion = "4.5.2"
|
||||
ext.jackson2Version = "2.8.1"
|
||||
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
|
||||
ext.javamailVersion = "1.5.5"
|
||||
ext.jettyVersion = "9.3.11.v20160721"
|
||||
ext.jodaVersion = "2.9.4"
|
||||
ext.jrubyVersion = "1.7.25" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.nettyVersion = "4.0.33.Final"
|
||||
ext.okhttpVersion = "2.7.0"
|
||||
ext.openjpaVersion = "2.4.0"
|
||||
ext.poiVersion = "3.13"
|
||||
ext.protobufVersion = "2.6.1"
|
||||
ext.reactorVersion = "2.0.7.RELEASE"
|
||||
ext.romeVersion = "1.5.1"
|
||||
ext.seleniumVersion = "2.48.2"
|
||||
ext.slf4jVersion = "1.7.13"
|
||||
ext.snakeyamlVersion = "1.16"
|
||||
ext.snifferVersion = "1.14"
|
||||
ext.log4jVersion = "1.2.17"
|
||||
ext.nettyVersion = "4.1.4.Final"
|
||||
ext.okhttpVersion = "2.7.5"
|
||||
ext.okhttp3Version = "3.4.1"
|
||||
ext.openjpaVersion = "2.4.1"
|
||||
ext.poiVersion = "3.14"
|
||||
ext.reactorVersion = "2.0.8.RELEASE"
|
||||
ext.romeVersion = "1.6.0"
|
||||
ext.slf4jVersion = "1.7.21"
|
||||
ext.snakeyamlVersion = "1.17"
|
||||
ext.snifferVersion = "1.15"
|
||||
ext.testngVersion = "6.9.10"
|
||||
ext.tiles2Version = "2.2.2"
|
||||
ext.tiles3Version = "3.0.5"
|
||||
ext.tomcatVersion = "8.0.30"
|
||||
ext.tomcatVersion = "8.5.4"
|
||||
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
|
||||
ext.undertowVersion = "1.3.10.Final"
|
||||
ext.woodstoxVersion = "5.0.1"
|
||||
ext.undertowVersion = "1.3.23.Final"
|
||||
ext.xmlunitVersion = "1.6"
|
||||
ext.xstreamVersion = "1.4.8"
|
||||
ext.xstreamVersion = "1.4.9"
|
||||
|
||||
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
|
||||
@@ -130,8 +131,6 @@ configure(allprojects) { project ->
|
||||
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
maven { url "https://repo.spring.io/snapshot" } // reactor 2.0.6 snapshot
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -197,13 +196,13 @@ configure(allprojects) { project ->
|
||||
"http://portals.apache.org/pluto/portlet-2.0-apidocs/",
|
||||
"http://tiles.apache.org/tiles-request/apidocs/",
|
||||
"http://tiles.apache.org/framework/apidocs/",
|
||||
"http://aopalliance.sourceforge.net/doc/",
|
||||
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"http://ehcache.org/apidocs/",
|
||||
"http://quartz-scheduler.org/api/2.2.0/",
|
||||
"http://fasterxml.github.com/jackson-core/javadoc/2.3.0/",
|
||||
"http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/",
|
||||
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.3.0/",
|
||||
"http://ehcache.org/apidocs/${ehcacheVersion}",
|
||||
"http://ehcache.org/apidocs/${ehcache3Version}",
|
||||
"http://quartz-scheduler.org/api/2.2.1/",
|
||||
"http://fasterxml.github.io/jackson-core/javadoc/2.7/",
|
||||
"http://fasterxml.github.io/jackson-databind/javadoc/2.7/",
|
||||
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.7/",
|
||||
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/"
|
||||
] as String[]
|
||||
}
|
||||
@@ -217,11 +216,11 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
|
||||
}
|
||||
|
||||
dependencies {
|
||||
jacoco("org.jacoco:org.jacoco.agent:0.7.1.201405082137:runtime")
|
||||
jacoco("org.jacoco:org.jacoco.agent:0.7.5.201505241946:runtime")
|
||||
}
|
||||
|
||||
gradle.taskGraph.whenReady {taskGraph ->
|
||||
if (taskGraph.hasTask(':sonarRunner')) {
|
||||
if (taskGraph.hasTask(':sonarqube')) {
|
||||
test.jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=org.springframework.*"
|
||||
}
|
||||
}
|
||||
@@ -287,12 +286,12 @@ project("spring-build-src") {
|
||||
project("spring-core") {
|
||||
description = "Spring Core"
|
||||
|
||||
// As of Spring 4.0.3, spring-core includes asm 5.0 and repackages cglib 3.2, inlining
|
||||
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.0 and is therefore
|
||||
// As of Spring 4.0.3, spring-core includes asm 5.x and repackages cglib 3.2, inlining
|
||||
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.x and is therefore
|
||||
// further transformed by the JarJar task to depend on org.springframework.asm; this
|
||||
// avoids including two different copies of asm unnecessarily.
|
||||
def cglibVersion = "3.2.0"
|
||||
def objenesisVersion = "2.2"
|
||||
def cglibVersion = "3.2.4"
|
||||
def objenesisVersion = "2.4"
|
||||
|
||||
configurations {
|
||||
jarjar
|
||||
@@ -352,11 +351,11 @@ project("spring-core") {
|
||||
compile("commons-logging:commons-logging:1.2")
|
||||
optional("commons-codec:commons-codec:1.10")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("net.sf.jopt-simple:jopt-simple:4.9")
|
||||
optional("log4j:log4j:1.2.17")
|
||||
optional("net.sf.jopt-simple:jopt-simple:5.0.2")
|
||||
optional("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:${woodstoxVersion}") {
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.2") {
|
||||
exclude group: "stax", module: "stax-api"
|
||||
}
|
||||
}
|
||||
@@ -384,9 +383,9 @@ project("spring-beans") {
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.yaml:snakeyaml:${snakeyamlVersion}")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-beans-groovy") {
|
||||
@@ -423,7 +422,6 @@ project("spring-aop") {
|
||||
compile(project(":spring-core"))
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
compile(files(project(":spring-core").objenesisRepackJar))
|
||||
compile("aopalliance:aopalliance:1.0")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("commons-pool:commons-pool:1.6")
|
||||
optional("org.apache.commons:commons-pool2:2.4.2")
|
||||
@@ -477,7 +475,7 @@ project("spring-context") {
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
optional(project(":spring-instrument"))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
optional("javax.ejb:ejb-api:${ejbVersion}")
|
||||
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
|
||||
optional("javax.money:money-api:1.0")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
@@ -489,7 +487,7 @@ project("spring-context") {
|
||||
optional("org.beanshell:bsh:2.0b4")
|
||||
optional("org.jruby:jruby:${jrubyVersion}")
|
||||
testCompile("javax.inject:javax.inject-tck:1")
|
||||
testCompile("org.javamoney:moneta:1.0")
|
||||
testCompile("org.javamoney:moneta:1.1")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("org.apache.commons:commons-pool2:2.4.2")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
@@ -528,10 +526,9 @@ project("spring-messaging") {
|
||||
}
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
}
|
||||
@@ -545,13 +542,13 @@ project("spring-tx") {
|
||||
compile(project(":spring-core"))
|
||||
optional(project(":spring-aop"))
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
optional("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
optional("javax.ejb:ejb-api:${ejbVersion}")
|
||||
optional("com.ibm.websphere:uow:6.0.2.17")
|
||||
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
testCompile("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
testCompile("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,22 +556,10 @@ project("spring-oxm") {
|
||||
description = "Spring Object/XML Marshalling"
|
||||
apply from: "oxm.gradle"
|
||||
|
||||
compileTestJava {
|
||||
// necessary to avoid java.lang.VerifyError on jibx compilation
|
||||
// see http://jira.codehaus.org/browse/JIBX-465
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
}
|
||||
|
||||
if (!System.getProperty("java.version").contains("1.8.")) {
|
||||
// necessary because castor and xjc tasks cannot find the JDK's compiler on JDK 9
|
||||
compileTestJava.enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional("org.codehaus.castor:castor-xml:1.4.0") {
|
||||
optional("org.codehaus.castor:castor-xml:1.4.1") {
|
||||
exclude group: 'stax', module: 'stax-api'
|
||||
exclude group: "org.springframework", module: "spring-context"
|
||||
}
|
||||
@@ -592,11 +577,9 @@ project("spring-oxm") {
|
||||
testCompile("org.codehaus.jettison:jettison:1.3.7") {
|
||||
exclude group: 'stax', module: 'stax-api'
|
||||
}
|
||||
if (compileTestJava.enabled) {
|
||||
testCompile(files(genCastor.classesDir).builtBy(genCastor))
|
||||
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
|
||||
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
|
||||
}
|
||||
testCompile(files(genCastor.classesDir).builtBy(genCastor))
|
||||
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
|
||||
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,7 +595,6 @@ project("spring-jms") {
|
||||
compile(project(":spring-tx"))
|
||||
provided("javax.jms:jms-api:1.1-rev-1")
|
||||
optional(project(":spring-oxm"))
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
@@ -630,7 +612,7 @@ project("spring-jdbc") {
|
||||
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
|
||||
optional("com.mchange:c3p0:0.9.5.2")
|
||||
optional("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
optional("com.h2database:h2:1.4.190")
|
||||
optional("com.h2database:h2:1.4.192")
|
||||
optional("org.apache.derby:derby:10.12.1.1")
|
||||
optional("org.apache.derby:derbyclient:10.12.1.1")
|
||||
}
|
||||
@@ -648,8 +630,9 @@ project("spring-context-support") {
|
||||
optional("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
optional("javax.cache:cache-api:1.0.0")
|
||||
optional("com.google.guava:guava:${guavaVersion}")
|
||||
optional("com.github.ben-manes.caffeine:caffeine:${caffeineVersion}")
|
||||
optional("net.sf.ehcache:ehcache:${ehcacheVersion}")
|
||||
optional("org.quartz-scheduler:quartz:2.2.2")
|
||||
optional("org.quartz-scheduler:quartz:2.2.3")
|
||||
optional("org.codehaus.fabric3.api:commonj:1.1.0")
|
||||
optional("org.apache.velocity:velocity:1.7")
|
||||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
@@ -704,7 +687,6 @@ project("spring-web") {
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("javax.faces:javax.faces-api:2.2")
|
||||
optional("javax.validation:validation-api:1.0.0.GA")
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("com.caucho:hessian:4.0.38")
|
||||
optional("commons-fileupload:commons-fileupload:${fileuploadVersion}")
|
||||
@@ -712,6 +694,7 @@ project("spring-web") {
|
||||
optional("org.apache.httpcomponents:httpasyncclient:${httpasyncVersion}")
|
||||
optional("io.netty:netty-all:${nettyVersion}")
|
||||
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
|
||||
optional("com.squareup.okhttp3:okhttp:${okhttp3Version}")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
|
||||
optional("com.google.code.gson:gson:${gsonVersion}")
|
||||
@@ -722,9 +705,9 @@ project("spring-web") {
|
||||
optional("org.eclipse.jetty:jetty-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
optional("log4j:log4j:1.2.17")
|
||||
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.2")
|
||||
optional("com.google.protobuf:protobuf-java:${protobufVersion}")
|
||||
optional("log4j:log4j:${log4jVersion}")
|
||||
optional("com.google.protobuf:protobuf-java:2.6.1")
|
||||
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
|
||||
optional("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
@@ -733,58 +716,12 @@ project("spring-web") {
|
||||
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
|
||||
}
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk7:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson2Version}")
|
||||
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-websocket") {
|
||||
description = "Spring WebSocket"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-web"))
|
||||
optional(project(":spring-messaging"))
|
||||
optional(project(":spring-webmvc"))
|
||||
optional("javax.servlet:javax.servlet-api:3.1.0")
|
||||
optional("javax.websocket:javax.websocket-api:1.0")
|
||||
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
|
||||
}
|
||||
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
|
||||
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
|
||||
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
|
||||
optional("io.undertow:undertow-core:${undertowVersion}")
|
||||
optional("io.undertow:undertow-servlet:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
|
||||
}
|
||||
optional("io.undertow:undertow-websockets-jsr:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
|
||||
testCompile("io.projectreactor:reactor-net:${reactorVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-orm") {
|
||||
description = "Spring Object/Relational Mapping"
|
||||
|
||||
@@ -796,7 +733,6 @@ project("spring-orm") {
|
||||
optional(project(":spring-aop"))
|
||||
optional(project(":spring-context"))
|
||||
optional(project(":spring-web"))
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.5")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.core:${eclipselinkVersion}")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipselinkVersion}") {
|
||||
@@ -837,7 +773,6 @@ project("spring-orm-hibernate4") {
|
||||
optional("org.hibernate:hibernate-core:${hibernate4Version}")
|
||||
optional("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
testCompile("javax.validation:validation-api:1.1.0.GA")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibval5Version}")
|
||||
testCompile("javax.el:javax.el-api:2.2.5")
|
||||
@@ -854,10 +789,8 @@ project("spring-orm-hibernate5") {
|
||||
provided(project(":spring-tx"))
|
||||
optional(project(":spring-web"))
|
||||
optional("org.hibernate:hibernate-core:${hibernate5Version}")
|
||||
optional("org.hibernate:hibernate-entitymanager:${hibernate5Version}")
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,13 +798,14 @@ project("spring-webmvc") {
|
||||
description = "Spring Web MVC"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-aop"))
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-core"))
|
||||
compile(files(project(":spring-core").objenesisRepackJar))
|
||||
compile(project(":spring-expression"))
|
||||
compile(project(":spring-web"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
provided("javax.servlet:javax.servlet-api:3.1.0")
|
||||
optional(project(":spring-context-support")) // for Velocity support
|
||||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
@@ -913,9 +847,7 @@ project("spring-webmvc") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
exclude group: "org.springframework", module: "spring-web"
|
||||
}
|
||||
optional('org.webjars:webjars-locator:0.28')
|
||||
testCompile(project(":spring-aop"))
|
||||
testCompile("rhino:js:1.7R1")
|
||||
optional('org.webjars:webjars-locator:0.32')
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("dom4j:dom4j:1.6.1") {
|
||||
exclude group: "xml-apis", module: "xml-apis"
|
||||
@@ -938,9 +870,10 @@ project("spring-webmvc") {
|
||||
testCompile("commons-io:commons-io:1.3")
|
||||
testCompile("joda-time:joda-time:${jodaVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("org.jruby:jruby:${jrubyVersion}")
|
||||
testCompile("org.python:jython-standalone:2.5.3")
|
||||
testCompile("org.webjars:underscorejs:1.8.3")
|
||||
testCompile("org.mozilla:rhino:1.7.7.1")
|
||||
testRuntime("org.jruby:jruby:${jrubyVersion}")
|
||||
testRuntime("org.python:jython-standalone:2.5.3")
|
||||
testRuntime("org.webjars:underscorejs:1.8.3")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,6 +924,51 @@ project("spring-webmvc-portlet") {
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-websocket") {
|
||||
description = "Spring WebSocket"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-web"))
|
||||
optional(project(":spring-messaging"))
|
||||
optional(project(":spring-webmvc"))
|
||||
optional("javax.servlet:javax.servlet-api:3.1.0")
|
||||
optional("javax.websocket:javax.websocket-api:1.0")
|
||||
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
|
||||
}
|
||||
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
|
||||
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
|
||||
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
|
||||
optional("io.undertow:undertow-core:${undertowVersion}")
|
||||
optional("io.undertow:undertow-servlet:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
|
||||
}
|
||||
optional("io.undertow:undertow-websockets-jsr:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("io.projectreactor:reactor-net:${reactorVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-test") {
|
||||
description = "Spring TestContext Framework"
|
||||
|
||||
@@ -1004,6 +982,7 @@ project("spring-test") {
|
||||
optional(project(":spring-web"))
|
||||
optional(project(":spring-webmvc"))
|
||||
optional(project(":spring-webmvc-portlet"))
|
||||
optional(project(":spring-websocket"))
|
||||
optional("junit:junit:${junitVersion}")
|
||||
optional("org.testng:testng:${testngVersion}")
|
||||
optional("javax.inject:javax.inject:1")
|
||||
@@ -1015,18 +994,20 @@ project("spring-test") {
|
||||
}
|
||||
optional("javax.portlet:portlet-api:2.0")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("javax.websocket:javax.websocket-api:1.0")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("org.hamcrest:hamcrest-core:${hamcrestVersion}")
|
||||
optional("com.jayway.jsonpath:json-path:${jsonpathVersion}")
|
||||
optional("org.skyscreamer:jsonassert:${jsonassertVersion}")
|
||||
optional("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
optional("net.sourceforge.htmlunit:htmlunit:${htmlunitVersion}")
|
||||
optional("org.seleniumhq.selenium:selenium-htmlunit-driver:${seleniumVersion}")
|
||||
optional("net.sourceforge.htmlunit:htmlunit:2.22")
|
||||
optional("org.seleniumhq.selenium:htmlunit-driver:2.21")
|
||||
optional("org.seleniumhq.selenium:selenium-java:2.53.1")
|
||||
optional("org.skyscreamer:jsonassert:1.3.0")
|
||||
optional("com.jayway.jsonpath:json-path:2.2.0")
|
||||
testCompile(project(":spring-context-support"))
|
||||
testCompile(project(":spring-oxm"))
|
||||
testCompile("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
testCompile("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
testCompile("javax.ejb:ejb-api:${ejbVersion}")
|
||||
testCompile("org.hibernate:hibernate-core:${hibernate4Version}")
|
||||
testCompile("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibval5Version}")
|
||||
@@ -1044,6 +1025,7 @@ project("spring-test") {
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
|
||||
testCompile("javax.cache:cache-api:1.0.0")
|
||||
testRuntime("log4j:log4j:${log4jVersion}")
|
||||
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
|
||||
testRuntime("org.terracotta:management-model:2.0.0")
|
||||
}
|
||||
@@ -1080,8 +1062,8 @@ project("spring-aspects") {
|
||||
|
||||
dependencies {
|
||||
aspects(project(":spring-orm"))
|
||||
ajc("org.aspectj:aspectjtools:1.9.0.BETA-2") // for the ability to build on JDK 9, not exposed in the POMs yet
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}") // regular AspectJ version here, to be exposed in the POMs
|
||||
ajc("org.aspectj:aspectjtools:${aspectjVersion}")
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}")
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
@@ -1099,8 +1081,7 @@ project("spring-aspects") {
|
||||
|
||||
eclipse.project {
|
||||
natures += "org.eclipse.ajdt.ui.ajnature"
|
||||
buildCommands = [new org.gradle.plugins.ide.eclipse.model.
|
||||
BuildCommand("org.eclipse.ajdt.core.ajbuilder")]
|
||||
buildCommands = [new org.gradle.plugins.ide.eclipse.model.BuildCommand("org.eclipse.ajdt.core.ajbuilder")]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,10 +1120,8 @@ project("spring-framework-bom") {
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'sonar-runner'
|
||||
|
||||
sonarRunner {
|
||||
sonarProperties {
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.projectName", "Spring Framework"
|
||||
property "sonar.profile", "Spring Framework"
|
||||
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
|
||||
@@ -1170,9 +1149,7 @@ configure(rootProject) {
|
||||
separateOutputDirs = false
|
||||
backends = ['docbook']
|
||||
options doctype: 'book', eruby: 'erubis'
|
||||
attributes 'spring-version': project.version,
|
||||
'revnumber' : project.version,
|
||||
'docinfo' : ""
|
||||
attributes 'spring-version': project.version, 'revnumber': project.version, 'docinfo': ""
|
||||
}
|
||||
|
||||
reference {
|
||||
@@ -1308,7 +1285,7 @@ configure(rootProject) {
|
||||
baseName = "spring-framework"
|
||||
classifier = "dist"
|
||||
description = "Builds -${classifier} archive, containing all jars and docs, " +
|
||||
"suitable for community download page."
|
||||
"suitable for community download page."
|
||||
|
||||
ext.baseDir = "${baseName}-${project.version}";
|
||||
|
||||
@@ -1381,7 +1358,7 @@ configure(rootProject) {
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = "Generates gradlew[.bat] scripts"
|
||||
gradleVersion = "2.5"
|
||||
gradleVersion = "2.13"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
|
||||
@@ -1398,14 +1375,14 @@ configure(rootProject) {
|
||||
}
|
||||
|
||||
configure([project(':spring-build-src'), project(':spring-framework-bom')]) {
|
||||
sonarRunner {
|
||||
sonarqube {
|
||||
skipProject = true
|
||||
}
|
||||
}
|
||||
|
||||
configure(project(':spring-core')) {
|
||||
sonarRunner {
|
||||
sonarProperties {
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.exclusions",
|
||||
"src/main/java/org/springframework/cglib/**/*,src/main/java/org/springframework/asm/**/*"
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.2.4.BUILD-SNAPSHOT
|
||||
version=4.3.2.RELEASE
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Thu Jul 09 16:54:55 EEST 2015
|
||||
#Wed Jun 15 12:59:30 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
|
||||
|
||||
@@ -6,13 +6,31 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
GRADLE_OPTS="-XX:MaxMetaspaceSize=1024m -Xmx1024m $GRADLE_OPTS"
|
||||
DEFAULT_JVM_OPTS=""
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
GRADLE_OPTS="-XX:MaxMetaspaceSize=1024m -Xmx1024m $GRADLE_OPTS"
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
@@ -31,6 +49,7 @@ die ( ) {
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
@@ -41,31 +60,11 @@ case "`uname`" in
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -91,7 +90,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -115,6 +114,7 @@ fi
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
|
||||
Vendored
+5
-5
@@ -8,15 +8,15 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set GRADLE_OPTS=-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set GRADLE_OPTS=-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -47,7 +47,7 @@ echo location of your Java installation.
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
@@ -29,8 +29,8 @@ REM - generates OXM test classes to avoid errors on import into Eclipse
|
||||
REM - generates metadata for all subprojects
|
||||
REM - skips metadata gen for the root project (-x :eclipse) to work
|
||||
REM around Eclipse's inability to import hierarchical project structures
|
||||
REM SET COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
SET COMMAND=gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
|
||||
REM SET COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
SET COMMAND=gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
|
||||
|
||||
echo.
|
||||
echo -----------------------------------------------------------------------
|
||||
@@ -69,7 +69,7 @@ echo When the above is complete, return here and press the enter key.
|
||||
|
||||
pause
|
||||
|
||||
set COMMAND=gradlew :eclipse
|
||||
set COMMAND=gradlew --no-daemon :eclipse
|
||||
|
||||
echo.
|
||||
echo -----------------------------------------------------------------------
|
||||
|
||||
@@ -42,7 +42,7 @@ read
|
||||
# - generates metadata for all subprojects
|
||||
# - skips metadata gen for the root project (-x :eclipse) to work
|
||||
# around Eclipse's inability to import hierarchical project structures
|
||||
COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
|
||||
cat <<EOM
|
||||
|
||||
@@ -84,7 +84,7 @@ EOM
|
||||
|
||||
read
|
||||
|
||||
COMMAND="./gradlew :eclipse"
|
||||
COMMAND="./gradlew --no-daemon :eclipse"
|
||||
|
||||
cat <<EOM
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.aop;
|
||||
|
||||
/**
|
||||
* Tag interface for Advice. Implementations can be any type
|
||||
* of advice, such as Interceptors.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @version $Id: Advice.java,v 1.1 2004/03/19 17:02:16 johnsonr Exp $
|
||||
*/
|
||||
public interface Advice {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.aop;
|
||||
|
||||
/**
|
||||
* Superclass for all AOP infrastructure exceptions.
|
||||
* Unchecked, as such exceptions are fatal and end user
|
||||
* code shouldn't be forced to catch them.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Bob Lee
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructor for AspectException.
|
||||
* @param message the exception message
|
||||
*/
|
||||
public AspectException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AspectException.
|
||||
* @param message the exception message
|
||||
* @param cause the root cause, if any
|
||||
*/
|
||||
public AspectException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
/**
|
||||
* Intercepts the construction of a new object.
|
||||
*
|
||||
* <p>The user should implement the {@link
|
||||
* #construct(ConstructorInvocation)} method to modify the original
|
||||
* behavior. E.g. the following class implements a singleton
|
||||
* interceptor (allows only one unique instance for the intercepted
|
||||
* class):
|
||||
*
|
||||
* <pre class=code>
|
||||
* class DebuggingInterceptor implements ConstructorInterceptor {
|
||||
* Object instance=null;
|
||||
*
|
||||
* Object construct(ConstructorInvocation i) throws Throwable {
|
||||
* if(instance==null) {
|
||||
* return instance=i.proceed();
|
||||
* } else {
|
||||
* throw new Exception("singleton does not allow multiple instance");
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface ConstructorInterceptor extends Interceptor {
|
||||
|
||||
/**
|
||||
* Implement this method to perform extra treatments before and
|
||||
* after the construction of a new object. Polite implementations
|
||||
* would certainly like to invoke {@link Joinpoint#proceed()}.
|
||||
* @param invocation the construction joinpoint
|
||||
* @return the newly created object, which is also the result of
|
||||
* the call to {@link Joinpoint#proceed()}; might be replaced by
|
||||
* the interceptor
|
||||
* @throws Throwable if the interceptors or the target object
|
||||
* throws an exception
|
||||
*/
|
||||
Object construct(ConstructorInvocation invocation) throws Throwable;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* Description of an invocation to a constuctor, given to an
|
||||
* interceptor upon constructor-call.
|
||||
*
|
||||
* <p>A constructor invocation is a joinpoint and can be intercepted
|
||||
* by a constructor interceptor.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see ConstructorInterceptor
|
||||
*/
|
||||
public interface ConstructorInvocation extends Invocation {
|
||||
|
||||
/**
|
||||
* Get the constructor being called.
|
||||
* <p>This method is a friendly implementation of the
|
||||
* {@link Joinpoint#getStaticPart()} method (same result).
|
||||
* @return the constructor being called
|
||||
*/
|
||||
Constructor<?> getConstructor();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
|
||||
/**
|
||||
* This interface represents a generic interceptor.
|
||||
*
|
||||
* <p>A generic interceptor can intercept runtime events that occur
|
||||
* within a base program. Those events are materialized by (reified
|
||||
* in) joinpoints. Runtime joinpoints can be invocations, field
|
||||
* access, exceptions...
|
||||
*
|
||||
* <p>This interface is not used directly. Use the sub-interfaces
|
||||
* to intercept specific events. For instance, the following class
|
||||
* implements some specific interceptors in order to implement a
|
||||
* debugger:
|
||||
*
|
||||
* <pre class=code>
|
||||
* class DebuggingInterceptor implements MethodInterceptor,
|
||||
* ConstructorInterceptor, FieldInterceptor {
|
||||
*
|
||||
* Object invoke(MethodInvocation i) throws Throwable {
|
||||
* debug(i.getMethod(), i.getThis(), i.getArgs());
|
||||
* return i.proceed();
|
||||
* }
|
||||
*
|
||||
* Object construct(ConstructorInvocation i) throws Throwable {
|
||||
* debug(i.getConstructor(), i.getThis(), i.getArgs());
|
||||
* return i.proceed();
|
||||
* }
|
||||
*
|
||||
* Object get(FieldAccess fa) throws Throwable {
|
||||
* debug(fa.getField(), fa.getThis(), null);
|
||||
* return fa.proceed();
|
||||
* }
|
||||
*
|
||||
* Object set(FieldAccess fa) throws Throwable {
|
||||
* debug(fa.getField(), fa.getThis(), fa.getValueToSet());
|
||||
* return fa.proceed();
|
||||
* }
|
||||
*
|
||||
* void debug(AccessibleObject ao, Object this, Object value) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see Joinpoint
|
||||
*/
|
||||
public interface Interceptor extends Advice {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
/**
|
||||
* This interface represents an invocation in the program.
|
||||
*
|
||||
* <p>An invocation is a joinpoint and can be intercepted by an
|
||||
* interceptor.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface Invocation extends Joinpoint {
|
||||
|
||||
/**
|
||||
* Get the arguments as an array object.
|
||||
* It is possible to change element values within this
|
||||
* array to change the arguments.
|
||||
* @return the argument of the invocation
|
||||
*/
|
||||
Object[] getArguments();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
|
||||
/**
|
||||
* This interface represents a generic runtime joinpoint (in the AOP
|
||||
* terminology).
|
||||
*
|
||||
* <p>A runtime joinpoint is an <i>event</i> that occurs on a static
|
||||
* joinpoint (i.e. a location in a the program). For instance, an
|
||||
* invocation is the runtime joinpoint on a method (static joinpoint).
|
||||
* The static part of a given joinpoint can be generically retrieved
|
||||
* using the {@link #getStaticPart()} method.
|
||||
*
|
||||
* <p>In the context of an interception framework, a runtime joinpoint
|
||||
* is then the reification of an access to an accessible object (a
|
||||
* method, a constructor, a field), i.e. the static part of the
|
||||
* joinpoint. It is passed to the interceptors that are installed on
|
||||
* the static joinpoint.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see Interceptor
|
||||
*/
|
||||
public interface Joinpoint {
|
||||
|
||||
/**
|
||||
* Proceed to the next interceptor in the chain.
|
||||
* <p>The implementation and the semantics of this method depends
|
||||
* on the actual joinpoint type (see the children interfaces).
|
||||
* @return see the children interfaces' proceed definition
|
||||
* @throws Throwable if the joinpoint throws an exception
|
||||
*/
|
||||
Object proceed() throws Throwable;
|
||||
|
||||
/**
|
||||
* Return the object that holds the current joinpoint's static part.
|
||||
* <p>For instance, the target object for an invocation.
|
||||
* @return the object (can be null if the accessible object is static)
|
||||
*/
|
||||
Object getThis();
|
||||
|
||||
/**
|
||||
* Return the static part of this joinpoint.
|
||||
* <p>The static part is an accessible object on which a chain of
|
||||
* interceptors are installed.
|
||||
*/
|
||||
AccessibleObject getStaticPart();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
/**
|
||||
* Intercepts calls on an interface on its way to the target. These
|
||||
* are nested "on top" of the target.
|
||||
*
|
||||
* <p>The user should implement the {@link #invoke(MethodInvocation)}
|
||||
* method to modify the original behavior. E.g. the following class
|
||||
* implements a tracing interceptor (traces all the calls on the
|
||||
* intercepted method(s)):
|
||||
*
|
||||
* <pre class=code>
|
||||
* class TracingInterceptor implements MethodInterceptor {
|
||||
* Object invoke(MethodInvocation i) throws Throwable {
|
||||
* System.out.println("method "+i.getMethod()+" is called on "+
|
||||
* i.getThis()+" with args "+i.getArguments());
|
||||
* Object ret=i.proceed();
|
||||
* System.out.println("method "+i.getMethod()+" returns "+ret);
|
||||
* return ret;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface MethodInterceptor extends Interceptor {
|
||||
|
||||
/**
|
||||
* Implement this method to perform extra treatments before and
|
||||
* after the invocation. Polite implementations would certainly
|
||||
* like to invoke {@link Joinpoint#proceed()}.
|
||||
* @param invocation the method invocation joinpoint
|
||||
* @return the result of the call to {@link Joinpoint#proceed()};
|
||||
* might be intercepted by the interceptor
|
||||
* @throws Throwable if the interceptors or the target object
|
||||
* throws an exception
|
||||
*/
|
||||
Object invoke(MethodInvocation invocation) throws Throwable;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Description of an invocation to a method, given to an interceptor
|
||||
* upon method-call.
|
||||
*
|
||||
* <p>A method invocation is a joinpoint and can be intercepted by a
|
||||
* method interceptor.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see MethodInterceptor
|
||||
*/
|
||||
public interface MethodInvocation extends Invocation {
|
||||
|
||||
/**
|
||||
* Get the method being called.
|
||||
* <p>This method is a frienly implementation of the
|
||||
* {@link Joinpoint#getStaticPart()} method (same result).
|
||||
* @return the method being called
|
||||
*/
|
||||
Method getMethod();
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,7 +86,7 @@ public interface MethodMatcher {
|
||||
* @return whether there's a runtime match
|
||||
* @see MethodMatcher#matches(Method, Class)
|
||||
*/
|
||||
boolean matches(Method method, Class<?> targetClass, Object[] args);
|
||||
boolean matches(Method method, Class<?> targetClass, Object... args);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,12 +29,14 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
|
||||
public static final TrueMethodMatcher INSTANCE = new TrueMethodMatcher();
|
||||
|
||||
|
||||
/**
|
||||
* Enforce Singleton pattern.
|
||||
*/
|
||||
private TrueMethodMatcher() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isRuntime() {
|
||||
return false;
|
||||
@@ -46,11 +48,17 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// Should never be invoked as isRuntime returns false.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodMatcher.TRUE";
|
||||
}
|
||||
|
||||
/**
|
||||
* Required to support serialization. Replaces with canonical
|
||||
* instance on deserialization, protecting Singleton pattern.
|
||||
@@ -60,9 +68,4 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodMatcher.TRUE";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+46
-28
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -55,7 +58,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation {
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
|
||||
|
||||
/**
|
||||
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
|
||||
@@ -86,10 +90,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
|
||||
protected final Method aspectJAdviceMethod;
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
/** The total number of arguments we have to populate on advice dispatch */
|
||||
private final int adviceInvocationArgumentCount;
|
||||
private final String methodName;
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
protected transient Method aspectJAdviceMethod;
|
||||
|
||||
private final AspectJExpressionPointcut pointcut;
|
||||
|
||||
@@ -135,7 +142,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
*/
|
||||
private int joinPointStaticPartArgumentIndex = -1;
|
||||
|
||||
private Map<String, Integer> argumentBindings = null;
|
||||
private Map<String, Integer> argumentBindings;
|
||||
|
||||
private boolean argumentsIntrospected = false;
|
||||
|
||||
@@ -154,8 +161,10 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) {
|
||||
|
||||
Assert.notNull(aspectJAdviceMethod, "Advice method must not be null");
|
||||
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
|
||||
this.methodName = aspectJAdviceMethod.getName();
|
||||
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
|
||||
this.aspectJAdviceMethod = aspectJAdviceMethod;
|
||||
this.adviceInvocationArgumentCount = this.aspectJAdviceMethod.getParameterTypes().length;
|
||||
this.pointcut = pointcut;
|
||||
this.aspectInstanceFactory = aspectInstanceFactory;
|
||||
}
|
||||
@@ -250,17 +259,17 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.argumentNames[i] + "' that is not a valid Java identifier");
|
||||
}
|
||||
}
|
||||
if (argumentNames != null) {
|
||||
if (aspectJAdviceMethod.getParameterTypes().length == argumentNames.length + 1) {
|
||||
if (this.argumentNames != null) {
|
||||
if (this.aspectJAdviceMethod.getParameterTypes().length == this.argumentNames.length + 1) {
|
||||
// May need to add implicit join point arg name...
|
||||
Class<?> firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
|
||||
Class<?> firstArgType = this.aspectJAdviceMethod.getParameterTypes()[0];
|
||||
if (firstArgType == JoinPoint.class ||
|
||||
firstArgType == ProceedingJoinPoint.class ||
|
||||
firstArgType == JoinPoint.StaticPart.class) {
|
||||
String[] oldNames = argumentNames;
|
||||
argumentNames = new String[oldNames.length + 1];
|
||||
argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, argumentNames, 1, oldNames.length);
|
||||
String[] oldNames = this.argumentNames;
|
||||
this.argumentNames = new String[oldNames.length + 1];
|
||||
this.argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, this.argumentNames, 1, oldNames.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,11 +368,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
*/
|
||||
public synchronized final void calculateArgumentBindings() {
|
||||
// The simple case... nothing to bind.
|
||||
if (this.argumentsIntrospected || this.adviceInvocationArgumentCount == 0) {
|
||||
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int numUnboundArgs = this.adviceInvocationArgumentCount;
|
||||
int numUnboundArgs = this.parameterTypes.length;
|
||||
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
|
||||
numUnboundArgs--;
|
||||
@@ -456,13 +465,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
|
||||
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
|
||||
if (this.argumentNames.length != numExpectedArgumentNames) {
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames
|
||||
+ " arguments to bind by name in advice, but actually found " +
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames +
|
||||
" arguments to bind by name in advice, but actually found " +
|
||||
this.argumentNames.length + " arguments.");
|
||||
}
|
||||
|
||||
// So we match in number...
|
||||
int argumentIndexOffset = this.adviceInvocationArgumentCount - numArgumentsLeftToBind;
|
||||
int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;
|
||||
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
|
||||
this.argumentBindings.put(this.argumentNames[i], i);
|
||||
}
|
||||
@@ -471,8 +480,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
// specified, and find the discovered argument types.
|
||||
if (this.returningName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.returningName)) {
|
||||
throw new IllegalStateException("Returning argument name '"
|
||||
+ this.returningName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Returning argument name '" + this.returningName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.returningName);
|
||||
@@ -482,8 +491,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
if (this.throwingName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.throwingName)) {
|
||||
throw new IllegalStateException("Throwing argument name '"
|
||||
+ this.throwingName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Throwing argument name '" + this.throwingName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.throwingName);
|
||||
@@ -543,7 +552,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
calculateArgumentBindings();
|
||||
|
||||
// AMC start
|
||||
Object[] adviceInvocationArgs = new Object[this.adviceInvocationArgumentCount];
|
||||
Object[] adviceInvocationArgs = new Object[this.parameterTypes.length];
|
||||
int numBound = 0;
|
||||
|
||||
if (this.joinPointArgumentIndex != -1) {
|
||||
@@ -580,11 +589,10 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
}
|
||||
|
||||
if (numBound != this.adviceInvocationArgumentCount) {
|
||||
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount
|
||||
+ " arguments, but only bound " + numBound + " (JoinPointMatch " +
|
||||
(jpMatch == null ? "was NOT" : "WAS") +
|
||||
" bound in invocation)");
|
||||
if (numBound != this.parameterTypes.length) {
|
||||
throw new IllegalStateException("Required to bind " + this.parameterTypes.length +
|
||||
" arguments, but only bound " + numBound + " (JoinPointMatch " +
|
||||
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
|
||||
}
|
||||
|
||||
return adviceInvocationArgs;
|
||||
@@ -665,6 +673,16 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
"aspect name '" + this.aspectName + "'";
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
inputStream.defaultReadObject();
|
||||
try {
|
||||
this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("Failed to find advice method on deserialization", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MethodMatcher that excludes the specified advice method.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
@@ -29,7 +30,9 @@ import org.springframework.aop.AfterAdvice;
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJAfterAdvice extends AbstractAspectJAdvice
|
||||
implements MethodInterceptor, AfterAdvice, Serializable {
|
||||
|
||||
public AspectJAfterAdvice(
|
||||
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
|
||||
@@ -37,6 +40,7 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@@ -32,7 +33,9 @@ import org.springframework.util.TypeUtils;
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
|
||||
implements AfterReturningAdvice, AfterAdvice, Serializable {
|
||||
|
||||
public AspectJAfterReturningAdvice(
|
||||
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
|
||||
@@ -40,6 +43,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -62,6 +66,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Following AspectJ semantics, if a returning clause was specified, then the
|
||||
* advice is only invoked if the returned value is an instance of the given
|
||||
@@ -96,7 +101,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
else if (Object.class == type && void.class == method.getReturnType()) {
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
return ClassUtils.isAssignable(type, method.getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
@@ -29,7 +30,9 @@ import org.springframework.aop.AfterAdvice;
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
|
||||
implements MethodInterceptor, AfterAdvice, Serializable {
|
||||
|
||||
public AspectJAfterThrowingAdvice(
|
||||
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
|
||||
@@ -37,6 +40,7 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -57,11 +61,11 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
try {
|
||||
return mi.proceed();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (shouldInvokeOnThrowing(t)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, t);
|
||||
catch (Throwable ex) {
|
||||
if (shouldInvokeOnThrowing(ex)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, ex);
|
||||
}
|
||||
throw t;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +73,8 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
* In AspectJ semantics, after throwing advice that specifies a throwing clause
|
||||
* is only invoked if the thrown exception is a subtype of the given throwing type.
|
||||
*/
|
||||
private boolean shouldInvokeOnThrowing(Throwable t) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(t.getClass());
|
||||
private boolean shouldInvokeOnThrowing(Throwable ex) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
@@ -33,7 +34,8 @@ import org.springframework.aop.ProxyMethodInvocation;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
|
||||
|
||||
public AspectJAroundAdvice(
|
||||
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
|
||||
@@ -41,6 +43,7 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
super(aspectJAroundAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -56,7 +59,6 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
|
||||
+1
-1
@@ -305,7 +305,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
checkReadyToMatch();
|
||||
ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
|
||||
ShadowMatch originalShadowMatch = getShadowMatch(method, method);
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
@@ -27,7 +28,8 @@ import org.springframework.aop.MethodBeforeAdvice;
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {
|
||||
|
||||
public AspectJMethodBeforeAdvice(
|
||||
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
|
||||
@@ -35,6 +37,7 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, null);
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
|
||||
/**
|
||||
* Private constructor to share common code between impl-based delegate and reference-based delegate
|
||||
* (cannot use method such as init() to share common code, due the the use of final fields)
|
||||
* (cannot use method such as init() to share common code, due the use of final fields)
|
||||
* @param interfaceType static field defining the introduction
|
||||
* @param typePattern type pattern the introduction is restricted to
|
||||
* @param implementationClass implementation class
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,10 +55,12 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
return this.aspectClass.newInstance();
|
||||
}
|
||||
catch (InstantiationException ex) {
|
||||
throw new AopConfigException("Unable to instantiate aspect class [" + this.aspectClass.getName() + "]", ex);
|
||||
throw new AopConfigException(
|
||||
"Unable to instantiate aspect class: " + this.aspectClass.getName(), ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new AopConfigException("Cannot access element class [" + this.aspectClass.getName() + "]", ex);
|
||||
throw new AopConfigException(
|
||||
"Could not access aspect constructor: " + this.aspectClass.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -29,7 +31,8 @@ import org.springframework.util.Assert;
|
||||
* @since 2.0
|
||||
* @see SimpleAspectInstanceFactory
|
||||
*/
|
||||
public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
|
||||
@SuppressWarnings("serial")
|
||||
public class SingletonAspectInstanceFactory implements AspectInstanceFactory, Serializable {
|
||||
|
||||
private final Object aspectInstance;
|
||||
|
||||
|
||||
+31
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,34 +61,6 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
private static final String AJC_MAGIC = "ajc$";
|
||||
|
||||
|
||||
/**
|
||||
* Find and return the first AspectJ annotation on the given method
|
||||
* (there <i>should</i> only be one anyway...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||||
Class<?>[] classesToLookFor = new Class<?>[] {
|
||||
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
|
||||
for (Class<?> c : classesToLookFor) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
|
||||
A result = AnnotationUtils.findAnnotation(method, toLookFor);
|
||||
if (result != null) {
|
||||
return new AspectJAnnotation<A>(result);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -181,6 +153,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
throw new IllegalStateException("Expecting at least " + argNames.length +
|
||||
" arguments in the advice declaration, but only found " + paramTypes.length);
|
||||
}
|
||||
|
||||
// Make the simplifying assumption for now that all of the JoinPoint based arguments
|
||||
// come first in the advice declaration.
|
||||
int typeOffset = paramTypes.length - argNames.length;
|
||||
@@ -191,7 +164,36 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find and return the first AspectJ annotation on the given method
|
||||
* (there <i>should</i> only be one anyway...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||||
Class<?>[] classesToLookFor = new Class<?>[] {
|
||||
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
|
||||
for (Class<?> c : classesToLookFor) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
|
||||
A result = AnnotationUtils.findAnnotation(method, toLookFor);
|
||||
if (result != null) {
|
||||
return new AspectJAnnotation<A>(result);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected enum AspectJAnnotationType {
|
||||
|
||||
AtPointcut,
|
||||
AtBefore,
|
||||
AtAfter,
|
||||
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,31 +63,31 @@ public interface AspectJAdvisorFactory {
|
||||
/**
|
||||
* Build Spring AOP Advisors for all annotated At-AspectJ methods
|
||||
* on the specified aspect instance.
|
||||
* @param aif the aspect instance factory (not the aspect instance itself
|
||||
* in order to avoid eager instantiation)
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* (not the aspect instance itself in order to avoid eager instantiation)
|
||||
* @return a list of advisors for this class
|
||||
*/
|
||||
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aif);
|
||||
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
|
||||
|
||||
/**
|
||||
* Build a Spring AOP Advisor for the given AspectJ advice method.
|
||||
* @param candidateAdviceMethod the candidate advice method
|
||||
* @param aif the aspect instance factory
|
||||
* @param declarationOrderInAspect the declaration order within the aspect
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* @param declarationOrder the declaration order within the aspect
|
||||
* @param aspectName the name of the aspect
|
||||
* @return {@code null} if the method is not an AspectJ advice method
|
||||
* or if it is a pointcut that will be used by other advice but will not
|
||||
* create a Spring advice in its own right
|
||||
*/
|
||||
Advisor getAdvisor(Method candidateAdviceMethod,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
|
||||
Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
|
||||
int declarationOrder, String aspectName);
|
||||
|
||||
/**
|
||||
* Build a Spring AOP Advice for the given AspectJ advice method.
|
||||
* @param candidateAdviceMethod the candidate advice method
|
||||
* @param pointcut the corresponding AspectJ expression pointcut
|
||||
* @param aif the aspect instance factory
|
||||
* @param declarationOrderInAspect the declaration order within the aspect
|
||||
* @param expressionPointcut the AspectJ expression pointcut
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* @param declarationOrder the declaration order within the aspect
|
||||
* @param aspectName the name of the aspect
|
||||
* @return {@code null} if the method is not an AspectJ advice method
|
||||
* or if it is a pointcut that will be used by other advice but will not
|
||||
@@ -98,7 +98,7 @@ public interface AspectJAdvisorFactory {
|
||||
* @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
|
||||
* @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
|
||||
*/
|
||||
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut pointcut,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
|
||||
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
|
||||
|
||||
}
|
||||
|
||||
+31
-12
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.AjType;
|
||||
import org.aspectj.lang.reflect.AjTypeSystem;
|
||||
@@ -40,12 +44,27 @@ import org.springframework.aop.support.ComposablePointcut;
|
||||
* @since 2.0
|
||||
* @see org.springframework.aop.aspectj.AspectJExpressionPointcut
|
||||
*/
|
||||
public class AspectMetadata {
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectMetadata implements Serializable {
|
||||
|
||||
/**
|
||||
* The name of this aspect as defined to Spring (the bean name) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
private final String aspectName;
|
||||
|
||||
/**
|
||||
* The aspect class, stored separately for re-resolution of the
|
||||
* corresponding AjType on deserialization.
|
||||
*/
|
||||
private final Class<?> aspectClass;
|
||||
|
||||
/**
|
||||
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
|
||||
* Re-resolved on deserialization since it isn't serializable itself.
|
||||
*/
|
||||
private final AjType<?> ajType;
|
||||
private transient AjType<?> ajType;
|
||||
|
||||
/**
|
||||
* Spring AOP pointcut corresponding to the per clause of the
|
||||
@@ -54,13 +73,6 @@ public class AspectMetadata {
|
||||
*/
|
||||
private final Pointcut perClausePointcut;
|
||||
|
||||
/**
|
||||
* The name of this aspect as defined to Spring (the bean name) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
private String aspectName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AspectMetadata instance for the given aspect class.
|
||||
@@ -83,10 +95,11 @@ public class AspectMetadata {
|
||||
if (ajType == null) {
|
||||
throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
|
||||
}
|
||||
this.ajType = ajType;
|
||||
if (this.ajType.getDeclarePrecedence().length > 0) {
|
||||
if (ajType.getDeclarePrecedence().length > 0) {
|
||||
throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
|
||||
}
|
||||
this.aspectClass = ajType.getJavaClass();
|
||||
this.ajType = ajType;
|
||||
|
||||
switch (this.ajType.getPerClause().getKind()) {
|
||||
case SINGLETON :
|
||||
@@ -132,7 +145,7 @@ public class AspectMetadata {
|
||||
* Return the aspect class.
|
||||
*/
|
||||
public Class<?> getAspectClass() {
|
||||
return this.ajType.getJavaClass();
|
||||
return this.aspectClass;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,4 +186,10 @@ public class AspectMetadata {
|
||||
return (isPerThisOrPerTarget() || isPerTypeWithin());
|
||||
}
|
||||
|
||||
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
inputStream.defaultReadObject();
|
||||
this.ajType = AjTypeSystem.getAjType(this.aspectClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.OrderUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -37,7 +40,8 @@ import org.springframework.util.ClassUtils;
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see LazySingletonAspectInstanceFactoryDecorator
|
||||
*/
|
||||
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
|
||||
@SuppressWarnings("serial")
|
||||
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory, Serializable {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
@@ -66,6 +70,8 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
* @param type the type that should be introspected by AspectJ
|
||||
*/
|
||||
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
Assert.notNull(name, "Bean name must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
this.name = name;
|
||||
this.aspectMetadata = new AspectMetadata(type, name);
|
||||
@@ -79,12 +85,9 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
|
||||
}
|
||||
else {
|
||||
return ClassUtils.getDefaultClassLoader();
|
||||
}
|
||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,6 +95,12 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
return this.aspectMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the order for this factory's target aspect, either
|
||||
* an instance-specific order expressed through implementing the
|
||||
|
||||
+53
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
@@ -37,58 +40,70 @@ import org.springframework.aop.support.Pointcuts;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class InstantiationModelAwarePointcutAdvisorImpl
|
||||
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation {
|
||||
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
|
||||
|
||||
private final AspectJExpressionPointcut declaredPointcut;
|
||||
|
||||
private Pointcut pointcut;
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
private final String methodName;
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
private transient Method aspectJAdviceMethod;
|
||||
|
||||
private final AspectJAdvisorFactory aspectJAdvisorFactory;
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
|
||||
|
||||
private final Method method;
|
||||
private final int declarationOrder;
|
||||
|
||||
private final String aspectName;
|
||||
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final boolean lazy;
|
||||
|
||||
private final AspectJAdvisorFactory atAspectJAdvisorFactory;
|
||||
|
||||
private Advice instantiatedAdvice;
|
||||
|
||||
private int declarationOrder;
|
||||
|
||||
private String aspectName;
|
||||
|
||||
private Boolean isBeforeAdvice;
|
||||
|
||||
private Boolean isAfterAdvice;
|
||||
|
||||
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
|
||||
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
|
||||
|
||||
this.declaredPointcut = ajexp;
|
||||
this.method = method;
|
||||
this.atAspectJAdvisorFactory = af;
|
||||
this.aspectInstanceFactory = aif;
|
||||
this.declarationOrder = declarationOrderInAspect;
|
||||
this.declaredPointcut = declaredPointcut;
|
||||
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
|
||||
this.methodName = aspectJAdviceMethod.getName();
|
||||
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
|
||||
this.aspectJAdviceMethod = aspectJAdviceMethod;
|
||||
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
|
||||
this.aspectInstanceFactory = aspectInstanceFactory;
|
||||
this.declarationOrder = declarationOrder;
|
||||
this.aspectName = aspectName;
|
||||
|
||||
if (aif.getAspectMetadata().isLazilyInstantiated()) {
|
||||
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
|
||||
// Static part of the pointcut is a lazy type.
|
||||
Pointcut preInstantiationPointcut =
|
||||
Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
|
||||
Pointcut preInstantiationPointcut = Pointcuts.union(
|
||||
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
|
||||
|
||||
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
|
||||
// If it's not a dynamic pointcut, it may be optimized out
|
||||
// by the Spring AOP infrastructure after the first evaluation.
|
||||
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif);
|
||||
this.pointcut = new PerTargetInstantiationModelPointcut(
|
||||
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
|
||||
this.lazy = true;
|
||||
}
|
||||
else {
|
||||
// A singleton aspect.
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
this.pointcut = declaredPointcut;
|
||||
this.pointcut = this.declaredPointcut;
|
||||
this.lazy = false;
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +157,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
|
||||
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
|
||||
return this.atAspectJAdvisorFactory.getAdvice(
|
||||
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
|
||||
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
}
|
||||
|
||||
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
|
||||
@@ -191,7 +206,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
*/
|
||||
private void determineAdviceType() {
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method);
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.aspectJAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
this.isBeforeAdvice = false;
|
||||
this.isAfterAdvice = false;
|
||||
@@ -220,11 +235,21 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
|
||||
"]; advice method [" + this.method + "]; perClauseKind=" +
|
||||
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
|
||||
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
|
||||
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
inputStream.defaultReadObject();
|
||||
try {
|
||||
this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("Failed to find advice method on deserialization", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pointcut implementation that changes its behaviour when the advice is instantiated.
|
||||
@@ -256,7 +281,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// This can match only on declared pointcut.
|
||||
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
|
||||
}
|
||||
|
||||
+12
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -25,7 +27,8 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory {
|
||||
@SuppressWarnings("serial")
|
||||
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory, Serializable {
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory maaif;
|
||||
|
||||
@@ -43,9 +46,9 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized Object getAspectInstance() {
|
||||
public Object getAspectInstance() {
|
||||
if (this.materialized == null) {
|
||||
synchronized (this) {
|
||||
synchronized (this.maaif.getAspectCreationMutex()) {
|
||||
if (this.materialized == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
}
|
||||
@@ -68,6 +71,11 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
return this.maaif.getAspectMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this.maaif.getAspectCreationMutex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.maaif.getOrder();
|
||||
|
||||
+8
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,4 +39,11 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
|
||||
*/
|
||||
AspectMetadata getAspectMetadata();
|
||||
|
||||
/**
|
||||
* Return the best possible creation mutex for this factory.
|
||||
* @return the mutex object (never {@code null})
|
||||
* @since 4.3
|
||||
*/
|
||||
Object getAspectCreationMutex();
|
||||
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,13 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* AspectInstanceFactory backed by a BeanFactory-provided prototype,
|
||||
* enforcing prototype semantics.
|
||||
* {@link org.springframework.aop.aspectj.AspectInstanceFactory} backed by a
|
||||
* {@link BeanFactory}-provided prototype, enforcing prototype semantics.
|
||||
*
|
||||
* <p>Note that this may instantiate multiple times, which probably won't give the
|
||||
* semantics you expect. Use a {@link LazySingletonAspectInstanceFactoryDecorator}
|
||||
@@ -32,7 +34,8 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see LazySingletonAspectInstanceFactoryDecorator
|
||||
*/
|
||||
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory {
|
||||
@SuppressWarnings("serial")
|
||||
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory implements Serializable {
|
||||
|
||||
/**
|
||||
* Create a PrototypeAspectInstanceFactory. AspectJ will be called to
|
||||
|
||||
+38
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -65,7 +66,8 @@ import org.springframework.util.comparator.InstanceComparator;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory {
|
||||
@SuppressWarnings("serial")
|
||||
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
|
||||
|
||||
private static final Comparator<Method> METHOD_COMPARATOR;
|
||||
|
||||
@@ -77,8 +79,9 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new Converter<Method, Annotation>() {
|
||||
@Override
|
||||
public Annotation convert(Method method) {
|
||||
AspectJAnnotation<?> annotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return annotation == null ? null : annotation.getAnnotation();
|
||||
AspectJAnnotation<?> annotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (annotation != null ? annotation.getAnnotation() : null);
|
||||
}
|
||||
}));
|
||||
comparator.addComparator(new ConvertingComparator<Method, String>(
|
||||
@@ -93,17 +96,17 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
|
||||
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
|
||||
final String aspectName = maaif.getAspectMetadata().getAspectName();
|
||||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
|
||||
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||||
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
|
||||
validate(aspectClass);
|
||||
|
||||
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
|
||||
// so that it will only instantiate once.
|
||||
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
|
||||
new LazySingletonAspectInstanceFactoryDecorator(maaif);
|
||||
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
|
||||
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
|
||||
|
||||
final List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
for (Method method : getAdvisorMethods(aspectClass)) {
|
||||
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
|
||||
if (advisor != null) {
|
||||
@@ -169,18 +172,19 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
|
||||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
|
||||
int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
validate(aif.getAspectMetadata().getAspectClass());
|
||||
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||||
|
||||
AspectJExpressionPointcut ajexp =
|
||||
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
|
||||
if (ajexp == null) {
|
||||
AspectJExpressionPointcut expressionPointcut = getPointcut(
|
||||
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||||
if (expressionPointcut == null) {
|
||||
return null;
|
||||
}
|
||||
return new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
|
||||
|
||||
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
|
||||
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
|
||||
@@ -189,6 +193,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
if (aspectJAnnotation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AspectJExpressionPointcut ajexp =
|
||||
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
|
||||
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
|
||||
@@ -197,10 +202,10 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
|
||||
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
|
||||
|
||||
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
|
||||
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||||
validate(candidateAspectClass);
|
||||
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
@@ -225,27 +230,32 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
switch (aspectJAnnotation.getAnnotationType()) {
|
||||
case AtBefore:
|
||||
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJMethodBeforeAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtAfter:
|
||||
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtAfterReturning:
|
||||
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterReturningAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
|
||||
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
|
||||
springAdvice.setReturningName(afterReturningAnnotation.returning());
|
||||
}
|
||||
break;
|
||||
case AtAfterThrowing:
|
||||
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterThrowingAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
|
||||
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
|
||||
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
|
||||
}
|
||||
break;
|
||||
case AtAround:
|
||||
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAroundAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtPointcut:
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -254,12 +264,12 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return null;
|
||||
default:
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported advice type on method " + candidateAdviceMethod);
|
||||
"Unsupported advice type on method: " + candidateAdviceMethod);
|
||||
}
|
||||
|
||||
// Now to configure the advice...
|
||||
springAdvice.setAspectName(aspectName);
|
||||
springAdvice.setDeclarationOrder(declarationOrderInAspect);
|
||||
springAdvice.setDeclarationOrder(declarationOrder);
|
||||
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
|
||||
if (argNames != null) {
|
||||
springAdvice.setArgumentNamesFromStringArray(argNames);
|
||||
@@ -268,6 +278,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return springAdvice;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synthetic advisor that instantiates the aspect.
|
||||
* Triggered by per-clause pointcut on non-singleton aspect.
|
||||
|
||||
+6
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,11 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
|
||||
|
||||
+10
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.OrderUtils;
|
||||
@@ -30,8 +32,9 @@ import org.springframework.core.annotation.OrderUtils;
|
||||
* @since 2.0
|
||||
* @see SimpleMetadataAwareAspectInstanceFactory
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspectInstanceFactory
|
||||
implements MetadataAwareAspectInstanceFactory {
|
||||
implements MetadataAwareAspectInstanceFactory, Serializable {
|
||||
|
||||
private final AspectMetadata metadata;
|
||||
|
||||
@@ -52,6 +55,11 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -97,7 +97,7 @@ public abstract class AopConfigUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
|
||||
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
|
||||
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -113,7 +113,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* Create a AdvisedSupport instance with the given parameters.
|
||||
* @param interfaces the proxied interfaces
|
||||
*/
|
||||
public AdvisedSupport(Class<?>[] interfaces) {
|
||||
public AdvisedSupport(Class<?>... interfaces) {
|
||||
this();
|
||||
setInterfaces(interfaces);
|
||||
}
|
||||
@@ -586,7 +586,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* Simple wrapper class around a Method. Used as the key when
|
||||
* caching methods, for efficient equals and hashCode comparisons.
|
||||
*/
|
||||
private static class MethodCacheKey {
|
||||
private static final class MethodCacheKey implements Comparable<MethodCacheKey> {
|
||||
|
||||
private final Method method;
|
||||
|
||||
@@ -599,17 +599,28 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
MethodCacheKey otherKey = (MethodCacheKey) other;
|
||||
return (this.method == otherKey.method);
|
||||
return (this == other || (other instanceof MethodCacheKey &&
|
||||
this.method == ((MethodCacheKey) other).method));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.method.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodCacheKey other) {
|
||||
int result = this.method.getName().compareTo(other.method.getName());
|
||||
if (result == 0) {
|
||||
result = this.method.toString().compareTo(other.method.toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import org.springframework.aop.TargetClassAware;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.target.SingletonTargetSource;
|
||||
import org.springframework.core.DecoratingProxy;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -78,11 +79,29 @@ public abstract class AopProxyUtils {
|
||||
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
|
||||
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
|
||||
* {@link org.springframework.aop.SpringProxy} marker interface.
|
||||
* @param advised the proxy config
|
||||
* @return the complete set of interfaces to proxy
|
||||
* @see SpringProxy
|
||||
* @see Advised
|
||||
* @see org.springframework.aop.SpringProxy
|
||||
*/
|
||||
public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
|
||||
return completeProxiedInterfaces(advised, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the complete set of interfaces to proxy for the given AOP configuration.
|
||||
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
|
||||
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
|
||||
* {@link org.springframework.aop.SpringProxy} marker interface.
|
||||
* @param advised the proxy config
|
||||
* @param decoratingProxy whether to expose the {@link DecoratingProxy} interface
|
||||
* @return the complete set of interfaces to proxy
|
||||
* @since 4.3
|
||||
* @see SpringProxy
|
||||
* @see Advised
|
||||
* @see DecoratingProxy
|
||||
*/
|
||||
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
|
||||
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
if (specifiedInterfaces.length == 0) {
|
||||
// No user-specified interfaces: check whether target class is an interface.
|
||||
@@ -99,6 +118,7 @@ public abstract class AopProxyUtils {
|
||||
}
|
||||
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
|
||||
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
|
||||
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
|
||||
int nonUserIfcCount = 0;
|
||||
if (addSpringProxy) {
|
||||
nonUserIfcCount++;
|
||||
@@ -106,13 +126,22 @@ public abstract class AopProxyUtils {
|
||||
if (addAdvised) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
if (addDecoratingProxy) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
|
||||
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
|
||||
int index = specifiedInterfaces.length;
|
||||
if (addSpringProxy) {
|
||||
proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
|
||||
proxiedInterfaces[index] = SpringProxy.class;
|
||||
index++;
|
||||
}
|
||||
if (addAdvised) {
|
||||
proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class;
|
||||
proxiedInterfaces[index] = Advised.class;
|
||||
index++;
|
||||
}
|
||||
if (addDecoratingProxy) {
|
||||
proxiedInterfaces[index] = DecoratingProxy.class;
|
||||
}
|
||||
return proxiedInterfaces;
|
||||
}
|
||||
@@ -134,6 +163,9 @@ public abstract class AopProxyUtils {
|
||||
if (proxy instanceof Advised) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
if (proxy instanceof DecoratingProxy) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount];
|
||||
System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length);
|
||||
Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.aop.AopInvocationException;
|
||||
import org.springframework.aop.RawTargetAccess;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.core.DecoratingProxy;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -116,7 +117,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
|
||||
}
|
||||
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
|
||||
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
|
||||
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
|
||||
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
|
||||
}
|
||||
@@ -164,11 +165,15 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
// The target does not implement the equals(Object) method itself.
|
||||
return equals(args[0]);
|
||||
}
|
||||
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
|
||||
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
|
||||
// The target does not implement the hashCode() method itself.
|
||||
return hashCode();
|
||||
}
|
||||
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
|
||||
else if (method.getDeclaringClass() == DecoratingProxy.class) {
|
||||
// There is only getDecoratedClass() declared -> dispatch to proxy config.
|
||||
return AopProxyUtils.ultimateTargetClass(this.advised);
|
||||
}
|
||||
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
|
||||
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
|
||||
// Service invocations on ProxyConfig with the proxy config...
|
||||
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,9 @@ import org.springframework.aop.TargetSource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Factory for AOP proxies for programmatic use, rather than via a bean
|
||||
* factory. This class provides a simple way of obtaining and configuring
|
||||
* AOP proxies in code.
|
||||
* Factory for AOP proxies for programmatic use, rather than via declarative
|
||||
* setup in a bean factory. This class provides a simple way of obtaining
|
||||
* and configuring AOP proxy instances in custom user code.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -139,7 +139,8 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
|
||||
* @return whether the given interface is an internal language interface
|
||||
*/
|
||||
protected boolean isInternalLanguageInterface(Class<?> ifc) {
|
||||
return ifc.getName().equals("groovy.lang.GroovyObject");
|
||||
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
|
||||
ifc.getName().endsWith(".cglib.proxy.Factory"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
@@ -370,6 +371,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
*/
|
||||
protected boolean isInfrastructureClass(Class<?> beanClass) {
|
||||
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
|
||||
Pointcut.class.isAssignableFrom(beanClass) ||
|
||||
Advisor.class.isAssignableFrom(beanClass) ||
|
||||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
|
||||
if (retVal && logger.isTraceEnabled()) {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public abstract class AutoProxyUtils {
|
||||
* to be proxied with its target class (in case of it getting proxied in the first
|
||||
* place). The value is {@code Boolean.TRUE} or {@code Boolean.FALSE}.
|
||||
* <p>Proxy factories can set this attribute if they built a target class proxy
|
||||
* for a specific bean, and want to enforce that that bean can always be cast
|
||||
* for a specific bean, and want to enforce that bean can always be cast
|
||||
* to its target class (even if AOP advices get applied through auto-proxying).
|
||||
* @see #shouldProxyTargetClass
|
||||
*/
|
||||
|
||||
+116
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,9 +31,12 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -58,6 +61,15 @@ import org.springframework.util.concurrent.ListenableFuture;
|
||||
*/
|
||||
public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
|
||||
/**
|
||||
* The default name of the {@link TaskExecutor} bean to pick up: "taskExecutor".
|
||||
* <p>Note that the initial lookup happens by type; this is just the fallback
|
||||
* in case of multiple executor beans found in the context.
|
||||
* @since 4.2.6
|
||||
*/
|
||||
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor";
|
||||
|
||||
|
||||
// Java 8's CompletableFuture type present?
|
||||
private static final boolean completableFuturePresent = ClassUtils.isPresent(
|
||||
"java.util.concurrent.CompletableFuture", AsyncExecutionInterceptor.class.getClassLoader());
|
||||
@@ -67,7 +79,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
|
||||
private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap<Method, AsyncTaskExecutor>(16);
|
||||
|
||||
private Executor defaultExecutor;
|
||||
private volatile Executor defaultExecutor;
|
||||
|
||||
private AsyncUncaughtExceptionHandler exceptionHandler;
|
||||
|
||||
@@ -75,10 +87,22 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link AsyncExecutionAspectSupport}, using the provided default
|
||||
* executor unless individual async methods indicate via qualifier that a more
|
||||
* specific executor should be used.
|
||||
* @param defaultExecutor the executor to use when executing asynchronous methods
|
||||
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
|
||||
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
|
||||
* executor has been requested via a qualifier on the async method, in which case the
|
||||
* executor will be looked up at invocation time against the enclosing bean factory
|
||||
*/
|
||||
public AsyncExecutionAspectSupport(Executor defaultExecutor) {
|
||||
this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link AsyncExecutionAspectSupport} with the given exception handler.
|
||||
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
|
||||
* executor has been requested via a qualifier on the async method, in which case the
|
||||
* executor will be looked up at invocation time against the enclosing bean factory
|
||||
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use
|
||||
*/
|
||||
public AsyncExecutionAspectSupport(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
|
||||
@@ -86,23 +110,16 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
|
||||
*/
|
||||
public AsyncExecutionAspectSupport(Executor defaultExecutor) {
|
||||
this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Supply the executor to be used when executing async methods.
|
||||
* @param defaultExecutor the {@code Executor} (typically a Spring {@code
|
||||
* AsyncTaskExecutor} or {@link java.util.concurrent.ExecutorService}) to delegate to
|
||||
* unless a more specific executor has been requested via a qualifier on the async
|
||||
* method, in which case the executor will be looked up at invocation time against the
|
||||
* enclosing bean factory.
|
||||
* @see #getExecutorQualifier
|
||||
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
|
||||
* executor has been requested via a qualifier on the async method, in which case the
|
||||
* executor will be looked up at invocation time against the enclosing bean factory
|
||||
* @see #getExecutorQualifier(Method)
|
||||
* @see #setBeanFactory(BeanFactory)
|
||||
* @see #getDefaultExecutor(BeanFactory)
|
||||
*/
|
||||
public void setExecutor(Executor defaultExecutor) {
|
||||
this.defaultExecutor = defaultExecutor;
|
||||
@@ -117,7 +134,10 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link BeanFactory} to be used when looking up executors by qualifier.
|
||||
* Set the {@link BeanFactory} to be used when looking up executors by qualifier
|
||||
* or when relying on the default executor lookup algorithm.
|
||||
* @see #findQualifiedExecutor(BeanFactory, String)
|
||||
* @see #getDefaultExecutor(BeanFactory)
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
@@ -128,26 +148,32 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
/**
|
||||
* Determine the specific executor to use when executing the given method.
|
||||
* Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
|
||||
* @return the executor to use (or {@code null}, but just if no default executor has been set)
|
||||
* @return the executor to use (or {@code null}, but just if no default executor is available)
|
||||
*/
|
||||
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
|
||||
AsyncTaskExecutor executor = this.executors.get(method);
|
||||
if (executor == null) {
|
||||
Executor executorToUse = this.defaultExecutor;
|
||||
Executor targetExecutor;
|
||||
String qualifier = getExecutorQualifier(method);
|
||||
if (StringUtils.hasLength(qualifier)) {
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
|
||||
" to access qualified executor '" + qualifier + "'");
|
||||
}
|
||||
executorToUse = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
|
||||
this.beanFactory, Executor.class, qualifier);
|
||||
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
|
||||
}
|
||||
else if (executorToUse == null) {
|
||||
else {
|
||||
targetExecutor = this.defaultExecutor;
|
||||
if (targetExecutor == null) {
|
||||
synchronized (this.executors) {
|
||||
if (this.defaultExecutor == null) {
|
||||
this.defaultExecutor = getDefaultExecutor(this.beanFactory);
|
||||
}
|
||||
targetExecutor = this.defaultExecutor;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetExecutor == null) {
|
||||
return null;
|
||||
}
|
||||
executor = (executorToUse instanceof AsyncListenableTaskExecutor ?
|
||||
(AsyncListenableTaskExecutor) executorToUse : new TaskExecutorAdapter(executorToUse));
|
||||
executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
|
||||
(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
|
||||
this.executors.put(method, executor);
|
||||
}
|
||||
return executor;
|
||||
@@ -160,11 +186,69 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
* been specified and that the {@linkplain #setExecutor(Executor) default executor}
|
||||
* should be used.
|
||||
* @param method the method to inspect for executor qualifier metadata
|
||||
* @return the qualifier if specified, otherwise empty string or {@code null}
|
||||
* @return the qualifier if specified, otherwise empty String or {@code null}
|
||||
* @see #determineAsyncExecutor(Method)
|
||||
* @see #findQualifiedExecutor(BeanFactory, String)
|
||||
*/
|
||||
protected abstract String getExecutorQualifier(Method method);
|
||||
|
||||
/**
|
||||
* Retrieve a target executor for the given qualifier.
|
||||
* @param qualifier the qualifier to resolve
|
||||
* @return the target executor, or {@code null} if none available
|
||||
* @since 4.2.6
|
||||
* @see #getExecutorQualifier(Method)
|
||||
*/
|
||||
protected Executor findQualifiedExecutor(BeanFactory beanFactory, String qualifier) {
|
||||
if (beanFactory == null) {
|
||||
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
|
||||
" to access qualified executor '" + qualifier + "'");
|
||||
}
|
||||
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve or build a default executor for this advice instance.
|
||||
* An executor returned from here will be cached for further use.
|
||||
* <p>The default implementation searches for a unique {@link TaskExecutor} bean
|
||||
* in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
|
||||
* If neither of the two is resolvable, this implementation will return {@code null}.
|
||||
* @param beanFactory the BeanFactory to use for a default executor lookup
|
||||
* @return the default executor, or {@code null} if none available
|
||||
* @since 4.2.6
|
||||
* @see #findQualifiedExecutor(BeanFactory, String)
|
||||
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
|
||||
*/
|
||||
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
|
||||
if (beanFactory != null) {
|
||||
try {
|
||||
// Search for TaskExecutor bean... not plain Executor since that would
|
||||
// match with ScheduledExecutorService as well, which is unusable for
|
||||
// our purposes here. TaskExecutor is more clearly designed for it.
|
||||
return beanFactory.getBean(TaskExecutor.class);
|
||||
}
|
||||
catch (NoUniqueBeanDefinitionException ex) {
|
||||
try {
|
||||
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex2) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("More than one TaskExecutor bean found within the context, and none is named " +
|
||||
"'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly " +
|
||||
"as an alias) in order to use it for async processing: " + ex.getBeanNamesFound());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
logger.debug("Could not find default TaskExecutor bean", ex);
|
||||
// Giving up -> either using local default executor or none at all...
|
||||
logger.info("No TaskExecutor bean found for async processing");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegate for actually executing the given task with the chosen executor.
|
||||
* @param task the task to execute
|
||||
|
||||
+29
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,9 +26,11 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -65,22 +67,27 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
|
||||
|
||||
/**
|
||||
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
|
||||
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to;
|
||||
* as of 4.2.6, a local executor for this interceptor will be built otherwise
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor defaultExecutor) {
|
||||
super(defaultExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code AsyncExecutionInterceptor}.
|
||||
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to;
|
||||
* as of 4.2.6, a local executor for this interceptor will be built otherwise
|
||||
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
|
||||
super(defaultExecutor, exceptionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor defaultExecutor) {
|
||||
super(defaultExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercept the given method invocation, submit the actual calling of the method to
|
||||
@@ -136,6 +143,20 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport imple
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation searches for a unique {@link org.springframework.core.task.TaskExecutor}
|
||||
* bean in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
|
||||
* If neither of the two is resolvable (e.g. if no {@code BeanFactory} was configured at all),
|
||||
* this implementation falls back to a newly created {@link SimpleAsyncTaskExecutor} instance
|
||||
* for local use if no default could be found.
|
||||
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
|
||||
*/
|
||||
@Override
|
||||
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
|
||||
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
|
||||
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
|
||||
+27
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -72,8 +73,23 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
resetAdviceMonitor();
|
||||
}
|
||||
|
||||
private void resetAdviceMonitor() {
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
this.adviceMonitor = ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
|
||||
}
|
||||
else {
|
||||
this.adviceMonitor = new Object();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a particular instance of the target advice directly,
|
||||
* avoiding lazy resolution in {@link #getAdvice()}.
|
||||
* @since 3.1
|
||||
*/
|
||||
public void setAdvice(Advice advice) {
|
||||
synchronized (this.adviceMonitor) {
|
||||
this.advice = advice;
|
||||
@@ -93,7 +109,15 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ": advice bean '" + getAdviceBeanName() + "'";
|
||||
StringBuilder sb = new StringBuilder(getClass().getName());
|
||||
sb.append(": advice ");
|
||||
if (this.adviceBeanName != null) {
|
||||
sb.append("bean '").append(this.adviceBeanName).append("'");
|
||||
}
|
||||
else {
|
||||
sb.append(this.advice);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +130,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
ois.defaultReadObject();
|
||||
|
||||
// Initialize transient fields.
|
||||
this.adviceMonitor = new Object();
|
||||
resetAdviceMonitor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.support;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
@@ -34,6 +35,7 @@ import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.aop.TargetClassAware;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.MethodIntrospector;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -112,6 +114,30 @@ public abstract class AopUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an invocable method on the target type: either the given method itself
|
||||
* if actually exposed on the target type, or otherwise a corresponding method
|
||||
* on one of the target type's interfaces or on the target type itself.
|
||||
* @param method the method to check
|
||||
* @param targetType the target type to search methods on (typically an AOP proxy)
|
||||
* @return a corresponding invocable method on the target type
|
||||
* @throws IllegalStateException if the given method is not invocable on the given
|
||||
* target type (typically due to a proxy mismatch)
|
||||
* @since 4.3
|
||||
* @see MethodIntrospector#selectInvocableMethod(Method, Class)
|
||||
*/
|
||||
public static Method selectInvocableMethod(Method method, Class<?> targetType) {
|
||||
Method methodToUse = MethodIntrospector.selectInvocableMethod(method, targetType);
|
||||
if (Modifier.isPrivate(methodToUse.getModifiers()) && !Modifier.isStatic(methodToUse.getModifiers()) &&
|
||||
SpringProxy.class.isAssignableFrom(targetType)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Need to invoke method '%s' found on proxy for target class '%s' but cannot " +
|
||||
"be delegated to target bean. Switch its visibility to package or protected.",
|
||||
method.getName(), method.getDeclaringClass().getSimpleName()));
|
||||
}
|
||||
return methodToUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given method is an "equals" method.
|
||||
* @see java.lang.Object#equals
|
||||
@@ -196,6 +222,11 @@ public abstract class AopUtils {
|
||||
}
|
||||
|
||||
MethodMatcher methodMatcher = pc.getMethodMatcher();
|
||||
if (methodMatcher == MethodMatcher.TRUE) {
|
||||
// No need to iterate the methods if we're matching any method anyway...
|
||||
return true;
|
||||
}
|
||||
|
||||
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
|
||||
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
|
||||
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
|
||||
@@ -204,7 +235,7 @@ public abstract class AopUtils {
|
||||
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||||
classes.add(targetClass);
|
||||
for (Class<?> clazz : classes) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
|
||||
for (Method method : methods) {
|
||||
if ((introductionAwareMethodMatcher != null &&
|
||||
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -91,17 +91,17 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
++this.evaluations;
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
this.evaluations++;
|
||||
ControlFlow cflow = ControlFlowFactory.createControlFlow();
|
||||
return (this.methodName != null) ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz);
|
||||
return (this.methodName != null ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* It's useful to know how many times we've fired, for optimization.
|
||||
*/
|
||||
public int getEvaluations() {
|
||||
return evaluations;
|
||||
return this.evaluations;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -138,7 +138,7 @@ public abstract class MethodMatchers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
return this.mm1.matches(method, targetClass, args) || this.mm2.matches(method, targetClass, args);
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ public abstract class MethodMatchers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// Because a dynamic intersection may be composed of a static and dynamic part,
|
||||
// we must avoid calling the 3-arg matches method on a dynamic matcher, as
|
||||
// it will probably be an unsupported operation.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,7 +71,7 @@ public abstract class Pointcuts {
|
||||
* @param args arguments to the method
|
||||
* @return whether there's a runtime match
|
||||
*/
|
||||
public static boolean matches(Pointcut pointcut, Method method, Class<?> targetClass, Object[] args) {
|
||||
public static boolean matches(Pointcut pointcut, Method method, Class<?> targetClass, Object... args) {
|
||||
Assert.notNull(pointcut, "Pointcut must not be null");
|
||||
if (pointcut == Pointcut.TRUE) {
|
||||
return true;
|
||||
@@ -98,9 +98,9 @@ public abstract class Pointcuts {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getName().startsWith("set") &&
|
||||
method.getParameterTypes().length == 1 &&
|
||||
method.getReturnType() == Void.TYPE;
|
||||
return (method.getName().startsWith("set") &&
|
||||
method.getParameterTypes().length == 1 &&
|
||||
method.getReturnType() == Void.TYPE);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
@@ -119,8 +119,8 @@ public abstract class Pointcuts {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getName().startsWith("get") &&
|
||||
method.getParameterTypes().length == 0;
|
||||
return (method.getName().startsWith("get") &&
|
||||
method.getParameterTypes().length == 0);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ public abstract class StaticMethodMatcher implements MethodMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public final boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// should never be invoked because isRuntime() returns false
|
||||
throw new UnsupportedOperationException("Illegal MethodMatcher usage");
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframewor
|
||||
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
|
||||
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
|
||||
http\://www.springframework.org/schema/aop/spring-aop-4.2.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
|
||||
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
|
||||
http\://www.springframework.org/schema/aop/spring-aop-4.3.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
|
||||
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/aop"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
targetNamespace="http://www.springframework.org/schema/aop"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Framework's AOP support.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="config">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A section (compartmentalization) of AOP-specific configuration (including
|
||||
aspects, pointcuts, etc).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pointcut" type="pointcutType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A named pointcut definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.aop.Advisor"><![CDATA[
|
||||
A named advisor definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="aspect" type="aspectType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A named aspect definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Are class-based (CGLIB) proxies to be created? By default, standard
|
||||
Java interface-based proxies are created.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicate that the proxy should be exposed by the AOP framework as a
|
||||
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||
i.e. no guarantees that AopContext access will work.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="aspectj-autoproxy">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
|
||||
Enables the use of the @AspectJ style of Spring AOP.
|
||||
|
||||
See org.springframework.context.annotation.EnableAspectJAutoProxy Javadoc
|
||||
for information on code-based alternatives to this XML element.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicates that only @AspectJ beans with names matched by the (regex)
|
||||
pattern will be considered as defining aspects to use for Spring autoproxying.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Are class-based (CGLIB) proxies to be created? By default, standard
|
||||
Java interface-based proxies are created.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicate that the proxy should be exposed by the AOP framework as a
|
||||
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||
i.e. no guarantees that AopContext access will work.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="scoped-proxy">
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.aop.scope.ScopedProxyFactoryBean"><![CDATA[
|
||||
Marks a bean definition as being a scoped proxy.
|
||||
|
||||
A bean marked as such will be exposed via a proxy, with the 'real'
|
||||
bean instance being retrieved from some other source (such as a
|
||||
HttpSession) as and when required.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Are class-based (CGLIB) proxies to be created? This is the default; in order to
|
||||
switch to standard Java interface-based proxies, turn this flag to "false".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="aspectType">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="pointcut" type="pointcutType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A named pointcut definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="declare-parents" type="declareParentsType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Allows this aspect to introduce additional interfaces that the advised
|
||||
object will transparently implement.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="before" type="basicAdviceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A before advice definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="after" type="basicAdviceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
An after advice definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="after-returning" type="afterReturningAdviceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
An after-returning advice definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="after-throwing" type="afterThrowingAdviceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
An after-throwing advice definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="around" type="basicAdviceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
An around advice definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The unique identifier for an aspect.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ref" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the (backing) bean that encapsulates the aspect.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:token">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
|
||||
Controls the ordering of the execution of this aspect when multiple
|
||||
advice executes at a specific joinpoint.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="includeType">
|
||||
<xsd:attribute name="name" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.util.regex.Pattern"><![CDATA[
|
||||
The regular expression defining which beans are to be included in the
|
||||
list of @AspectJ beans; beans with names matched by the pattern will
|
||||
be included.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pointcutType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.aop.Pointcut"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The unique identifier for a pointcut.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression" use="required" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The pointcut expression.
|
||||
|
||||
For example : 'execution(* com.xyz.myapp.service.*.*(..))'
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="declareParentsType">
|
||||
<xsd:attribute name="types-matching" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.aop.aspectj.TypePatternClassFilter"><![CDATA[
|
||||
The AspectJ type expression that defines what types (classes) the
|
||||
introduction is restricted to.
|
||||
|
||||
An example would be 'org.springframework.beans.ITestBean+'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="implement-interface" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||
The fully qualified name of the interface that will be introduced.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default-impl" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||
The fully qualified name of the class that will be instantiated to serve
|
||||
as the default implementation of the introduced interface.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="delegate-ref" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the bean that will serve
|
||||
as the default implementation of the introduced interface.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="basicAdviceType">
|
||||
<xsd:attribute name="pointcut" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The associated pointcut expression.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of an associated pointcut definition.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Pointcut"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="method" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the method that defines the logic of the advice.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="arg-names" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The comma-delimited list of advice method argument (parameter) names
|
||||
that will be matched from pointcut parameters.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="afterReturningAdviceType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="basicAdviceType">
|
||||
<xsd:attribute name="returning" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the method parameter to which the return value must
|
||||
be passed.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="afterThrowingAdviceType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="basicAdviceType">
|
||||
<xsd:attribute name="throwing" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the method parameter to which the thrown exception must
|
||||
be passed.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="advisorType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.aop.Advisor"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
<xsd:attribute name="advice-ref" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to an advice bean.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.aopalliance.aop.Advice"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pointcut" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A pointcut expression.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a pointcut definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:token">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
|
||||
Controls the ordering of the execution of this advice when multiple
|
||||
advice executes at a specific joinpoint.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Pointcut"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
+2
-1
@@ -307,7 +307,8 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
try {
|
||||
discoverer.getParameterNames(m);
|
||||
fail("Expecting " + exceptionType.getName() + " with message '" + message + "'");
|
||||
} catch (RuntimeException expected) {
|
||||
}
|
||||
catch (RuntimeException expected) {
|
||||
assertEquals("Expecting exception of type " + exceptionType.getName(),
|
||||
exceptionType, expected.getClass());
|
||||
assertEquals("Exception message does not match expected", message, expected.getMessage());
|
||||
|
||||
+25
-37
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,17 +53,15 @@ public final class AspectJExpressionPointcutTests {
|
||||
|
||||
private Method setSomeNumber;
|
||||
|
||||
private Method isPostProcessed;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge", (Class<?>[])null);
|
||||
setAge = TestBean.class.getMethod("setAge", new Class[]{int.class});
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", new Class[]{Number.class});
|
||||
isPostProcessed = TestBean.class.getMethod("isPostProcessed", (Class[]) null);
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
setAge = TestBean.class.getMethod("setAge", int.class);
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchExplicit() {
|
||||
String expression = "execution(int org.springframework.tests.sample.beans.TestBean.getAge())";
|
||||
@@ -111,21 +109,9 @@ public final class AspectJExpressionPointcutTests {
|
||||
testThisOrTarget("target");
|
||||
}
|
||||
|
||||
public static class OtherIOther implements IOther {
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This and target are equivalent. Really instanceof pointcuts.
|
||||
* @param which this or target
|
||||
* @throws Exception
|
||||
* @throws NoSuchMethodException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
private void testThisOrTarget(String which) throws SecurityException, NoSuchMethodException {
|
||||
String matchesTestBean = which + "(org.springframework.tests.sample.beans.TestBean)";
|
||||
@@ -138,11 +124,8 @@ public final class AspectJExpressionPointcutTests {
|
||||
|
||||
assertTrue(testBeanPc.matches(TestBean.class));
|
||||
assertTrue(testBeanPc.matches(getAge, TestBean.class));
|
||||
assertTrue(iOtherPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
|
||||
assertFalse(testBeanPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
assertTrue(iOtherPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
assertFalse(testBeanPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -171,8 +154,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
assertEquals(matchSubpackages, withinBeansPc.matches(
|
||||
DeepBean.class.getMethod("aMethod", String.class), DeepBean.class));
|
||||
assertFalse(withinBeansPc.matches(String.class));
|
||||
assertFalse(withinBeansPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
assertFalse(withinBeansPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,7 +165,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +177,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +189,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,10 +208,10 @@ public final class AspectJExpressionPointcutTests {
|
||||
//assertDoesNotMatchStringClass(classFilter);
|
||||
|
||||
assertTrue("Should match with setSomeNumber with Double input",
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Object[]{new Double(12)}));
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Double(12)));
|
||||
assertFalse("Should not match setSomeNumber with Integer input",
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Object[]{new Integer(11)}));
|
||||
assertFalse("Should not match getAge", methodMatcher.matches(getAge, TestBean.class, null));
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Integer(11)));
|
||||
assertFalse("Should not match getAge", methodMatcher.matches(getAge, TestBean.class));
|
||||
assertTrue("Should be a runtime match", methodMatcher.isRuntime());
|
||||
}
|
||||
|
||||
@@ -281,7 +263,6 @@ public final class AspectJExpressionPointcutTests {
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
assertTrue(true);
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,16 +307,14 @@ public final class AspectJExpressionPointcutTests {
|
||||
@Test
|
||||
public void testAndSubstitution() {
|
||||
Pointcut pc = getPointcut("execution(* *(..)) and args(String)");
|
||||
PointcutExpression expr =
|
||||
((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
PointcutExpression expr = ((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
assertEquals("execution(* *(..)) && args(String)",expr.getPointcutExpression());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAndSubstitutions() {
|
||||
Pointcut pc = getPointcut("execution(* *(..)) and args(String) and this(Object)");
|
||||
PointcutExpression expr =
|
||||
((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
PointcutExpression expr = ((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
assertEquals("execution(* *(..)) && args(String) && this(Object)",expr.getPointcutExpression());
|
||||
}
|
||||
|
||||
@@ -344,6 +323,15 @@ public final class AspectJExpressionPointcutTests {
|
||||
pointcut.setExpression(expression);
|
||||
return pointcut;
|
||||
}
|
||||
|
||||
|
||||
public static class OtherIOther implements IOther {
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -215,7 +215,8 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||
itb.setSpouse(new TestBean());
|
||||
try {
|
||||
itb.unreliableFileOperation();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// we don't realy care...
|
||||
}
|
||||
}
|
||||
|
||||
+29
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,7 +36,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class TigerAspectJExpressionPointcutTests {
|
||||
public class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
// TODO factor into static in AspectJExpressionPointcut
|
||||
private Method getAge;
|
||||
@@ -46,7 +46,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge", (Class[]) null);
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
// Assumes no overloading
|
||||
for (Method m : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(m.getName(), m);
|
||||
@@ -54,18 +54,6 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.tests.sample.beans.TestBean>) )";
|
||||
@@ -132,15 +120,12 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws SecurityException, NoSuchMethodException {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertFalse(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class),
|
||||
TestBean.class));
|
||||
assertTrue(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo", (Class[]) null),
|
||||
SpringAnnotated.class));
|
||||
assertFalse(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class));
|
||||
assertTrue(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class));
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertFalse(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo", (Class[]) null),
|
||||
SpringAnnotated.class));
|
||||
assertFalse(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -154,7 +139,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertFalse(ajexp.matches(getAge, TestBean.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
@@ -168,10 +153,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertFalse(ajexp.matches(getAge, TestBean.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertTrue(ajexp.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertTrue(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
}
|
||||
|
||||
@@ -182,10 +167,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertFalse(anySpringMethodAnnotation.matches(getAge, TestBean.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertTrue(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertTrue(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
}
|
||||
|
||||
@@ -196,10 +181,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
|
||||
assertTrue(takesSpringAnnotatedArgument2.matches(
|
||||
@@ -213,8 +198,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class,
|
||||
new Object[] { new TestBean(), new BeanA()})
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -225,10 +209,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
|
||||
assertTrue(takesSpringAnnotatedArgument2.matches(
|
||||
@@ -240,6 +224,19 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
|
||||
+29
-6
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -97,12 +113,14 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
try {
|
||||
bean.sayHello();
|
||||
fail("Expected exception");
|
||||
} catch (TestException e) {
|
||||
assertEquals(message, e.getMessage());
|
||||
}
|
||||
catch (TestException ex) {
|
||||
assertEquals(message, ex.getMessage());
|
||||
}
|
||||
assertEquals(1, logAdvice.getCountThrows());
|
||||
}
|
||||
|
||||
|
||||
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
||||
|
||||
/**
|
||||
@@ -115,15 +133,16 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class TestException extends RuntimeException {
|
||||
|
||||
public TestException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@@ -131,18 +150,23 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
public static @interface Log {
|
||||
}
|
||||
|
||||
|
||||
public static interface TestService {
|
||||
|
||||
public String sayHello();
|
||||
}
|
||||
|
||||
|
||||
@Log
|
||||
public static class TestServiceImpl implements TestService {
|
||||
|
||||
@Override
|
||||
public String sayHello() {
|
||||
throw new TestException("TestServiceImpl");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
|
||||
|
||||
private int countBefore = 0;
|
||||
@@ -154,9 +178,9 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
public void afterThrowing(Exception e) throws Throwable {
|
||||
public void afterThrowing(Exception ex) throws Throwable {
|
||||
countThrows++;
|
||||
throw e;
|
||||
throw ex;
|
||||
}
|
||||
|
||||
public int getCountBefore() {
|
||||
@@ -171,7 +195,6 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
countThrows = 0;
|
||||
countBefore = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -692,6 +693,11 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
return new AspectMetadata(PerTypeWithinAspect.class, "perTypeWithin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
@@ -961,7 +967,7 @@ abstract class AbstractMakeModifiable {
|
||||
private Method getGetterFromSetter(Method setter) {
|
||||
String getterName = setter.getName().replaceFirst("set", "get");
|
||||
try {
|
||||
return setter.getDeclaringClass().getMethod(getterName, (Class[]) null);
|
||||
return setter.getDeclaringClass().getMethod(getterName);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// must be write only
|
||||
|
||||
+19
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,18 +31,21 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AspectJPointcutAdvisorTests {
|
||||
public class AspectJPointcutAdvisorTests {
|
||||
|
||||
private final AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
private AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
@Test
|
||||
public void testSingleton() throws SecurityException, NoSuchMethodException {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null),"someBean"),
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),1,"someBean");
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
ajexp, TestBean.class.getMethod("getAge"), af,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null), "someBean"),
|
||||
1, "someBean");
|
||||
|
||||
assertSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertFalse(ajpa.isPerInstance());
|
||||
}
|
||||
@@ -52,34 +55,35 @@ public final class AspectJPointcutAdvisorTests {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(),"someBean"), null, 1, "someBean");
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
ajexp, TestBean.class.getMethod("getAge"), af,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(), "someBean"),
|
||||
1, "someBean");
|
||||
|
||||
assertNotSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut() instanceof AspectJExpressionPointcut);
|
||||
assertTrue(ajpa.isPerInstance());
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getClassFilter().matches(TestBean.class));
|
||||
assertFalse(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getAge"), TestBean.class));
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getSpouse", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getSpouse"), TestBean.class));
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowAspect.class);
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowBelowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowBelowAspect.class);
|
||||
}
|
||||
|
||||
private void testIllegalInstantiationModel(Class<?> c) throws AopConfigException {
|
||||
new AspectMetadata(c,"someBean");
|
||||
new AspectMetadata(c, "someBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-8
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import test.aop.PerThisAspect;
|
||||
|
||||
@@ -80,7 +80,18 @@ public class AspectProxyFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // InstantiationModelAwarePointcutAdvisorImpl not serializable yet
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSerializable() throws Exception {
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
|
||||
proxyFactory.addAspect(LoggingAspectOnVarargs.class);
|
||||
ITestBean proxy = proxyFactory.getProxy();
|
||||
assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C));
|
||||
ITestBean tb = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
assertTrue(tb.doWithVarargs(MyEnum.A, MyOtherEnum.C));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testWithInstance() throws Exception {
|
||||
MultiplyReturnValue aspect = new MultiplyReturnValue();
|
||||
int multiple = 3;
|
||||
@@ -133,7 +144,8 @@ public class AspectProxyFactoryTests {
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean implements ITestBean {
|
||||
@SuppressWarnings("serial")
|
||||
public static class TestBean implements ITestBean, Serializable {
|
||||
|
||||
private int age;
|
||||
|
||||
@@ -171,7 +183,8 @@ public class AspectProxyFactoryTests {
|
||||
|
||||
|
||||
@Aspect
|
||||
public static class LoggingAspectOnVarargs {
|
||||
@SuppressWarnings("serial")
|
||||
public static class LoggingAspectOnVarargs implements Serializable {
|
||||
|
||||
@Around("execution(* doWithVarargs(*))")
|
||||
public Object doLog(ProceedingJoinPoint pjp) throws Throwable {
|
||||
@@ -193,11 +206,9 @@ public class AspectProxyFactoryTests {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
@Aspect
|
||||
class MultiplyReturnValue {
|
||||
@SuppressWarnings("serial")
|
||||
class MultiplyReturnValue implements Serializable {
|
||||
|
||||
private int multiple = 2;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.aop.framework;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -34,7 +32,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AopProxyUtilsTests {
|
||||
public class AopProxyUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testCompleteProxiedInterfacesWorksWithNull() {
|
||||
@@ -125,15 +123,10 @@ public final class AopProxyUtilsTests {
|
||||
assertEquals(Comparable.class, userInterfaces[1]);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testProxiedUserInterfacesWithNoInterface() {
|
||||
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[0],
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
(proxy1, method, args) -> null);
|
||||
AopProxyUtils.proxiedUserInterfaces(proxy);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ public final class MethodInvocationTests {
|
||||
|
||||
@Test
|
||||
public void testValidInvocation() throws Throwable {
|
||||
Method m = Object.class.getMethod("hashCode", (Class[]) null);
|
||||
Method m = Object.class.getMethod("hashCode");
|
||||
Object proxy = new Object();
|
||||
final Object returnValue = new Object();
|
||||
List<Object> is = new LinkedList<Object>();
|
||||
@@ -67,7 +67,7 @@ public final class MethodInvocationTests {
|
||||
};
|
||||
List<Object> is = new LinkedList<Object>();
|
||||
|
||||
Method m = Object.class.getMethod("hashCode", (Class[]) null);
|
||||
Method m = Object.class.getMethod("hashCode");
|
||||
Object proxy = new Object();
|
||||
ReflectiveMethodInvocation invocation =
|
||||
new ReflectiveMethodInvocation(proxy, target, m, null, null, is);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.aop.framework;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.RootPaneContainer;
|
||||
@@ -31,6 +33,8 @@ import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.tests.TimeStamped;
|
||||
import org.springframework.tests.aop.advice.CountingBeforeAdvice;
|
||||
import org.springframework.tests.aop.interceptor.NopInterceptor;
|
||||
@@ -49,7 +53,7 @@ import static org.junit.Assert.*;
|
||||
* @author Chris Beams
|
||||
* @since 14.05.2003
|
||||
*/
|
||||
public final class ProxyFactoryTests {
|
||||
public class ProxyFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testIndexOfMethods() {
|
||||
@@ -337,6 +341,34 @@ public final class ProxyFactoryTests {
|
||||
assertTrue(proxy instanceof Accessible);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterfaceProxiesCanBeOrderedThroughAnnotations() {
|
||||
Object proxy1 = new ProxyFactory(new A()).getProxy();
|
||||
Object proxy2 = new ProxyFactory(new B()).getProxy();
|
||||
List<Object> list = new ArrayList<Object>(2);
|
||||
list.add(proxy1);
|
||||
list.add(proxy2);
|
||||
AnnotationAwareOrderComparator.sort(list);
|
||||
assertSame(proxy2, list.get(0));
|
||||
assertSame(proxy1, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetClassProxiesCanBeOrderedThroughAnnotations() {
|
||||
ProxyFactory pf1 = new ProxyFactory(new A());
|
||||
pf1.setProxyTargetClass(true);
|
||||
ProxyFactory pf2 = new ProxyFactory(new B());
|
||||
pf2.setProxyTargetClass(true);
|
||||
Object proxy1 = pf1.getProxy();
|
||||
Object proxy2 = pf2.getProxy();
|
||||
List<Object> list = new ArrayList<Object>(2);
|
||||
list.add(proxy1);
|
||||
list.add(proxy2);
|
||||
AnnotationAwareOrderComparator.sort(list);
|
||||
assertSame(proxy2, list.get(0));
|
||||
assertSame(proxy1, list.get(1));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class TimestampIntroductionInterceptor extends DelegatingIntroductionInterceptor
|
||||
@@ -361,4 +393,22 @@ public final class ProxyFactoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Order(2)
|
||||
public static class A implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Order(1)
|
||||
public static class B implements Runnable{
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,7 +78,7 @@ public final class ThrowsAdviceInterceptorTests {
|
||||
ThrowsAdviceInterceptor ti = new ThrowsAdviceInterceptor(th);
|
||||
FileNotFoundException ex = new FileNotFoundException();
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.getMethod()).willReturn(Object.class.getMethod("hashCode", (Class[]) null));
|
||||
given(mi.getMethod()).willReturn(Object.class.getMethod("hashCode"));
|
||||
given(mi.getThis()).willReturn(new Object());
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
try {
|
||||
@@ -140,12 +140,15 @@ public final class ThrowsAdviceInterceptorTests {
|
||||
assertEquals(1, th.getCalls("remoteException"));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class MyThrowsHandler extends MethodCounter implements ThrowsAdvice {
|
||||
|
||||
// Full method signature
|
||||
public void afterThrowing(Method m, Object[] args, Object target, IOException ex) {
|
||||
count("ioException");
|
||||
}
|
||||
|
||||
public void afterThrowing(RemoteException ex) throws Throwable {
|
||||
count("remoteException");
|
||||
}
|
||||
|
||||
+2
-1
@@ -61,7 +61,8 @@ public final class DebugInterceptorTests {
|
||||
try {
|
||||
interceptor.invoke(methodInvocation);
|
||||
fail("Must have propagated the IllegalArgumentException.");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
checkCallCountTotal(interceptor);
|
||||
|
||||
|
||||
+2
-1
@@ -60,7 +60,8 @@ public final class SimpleTraceInterceptorTests {
|
||||
try {
|
||||
interceptor.invokeUnderTrace(mi, log);
|
||||
fail("Must have propagated the IllegalArgumentException.");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
verify(log).trace(anyString());
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,8 +54,8 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
}
|
||||
|
||||
protected void noPatternSuppliedTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
assertEquals(0, rpc.getPatterns().length);
|
||||
}
|
||||
|
||||
@@ -69,38 +69,38 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
|
||||
protected void exactMatchTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
// assumes rpc.setPattern("java.lang.Object.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecificMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.String.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcard() throws Exception {
|
||||
rpc.setPattern(".*Object.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcardForOneClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("wait", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("wait"), String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesObjectClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertTrue(rpc.matches(Exception.class.getMethod("hashCode", (Class[]) null), IOException.class));
|
||||
assertTrue(rpc.matches(Exception.class.getMethod("hashCode"), IOException.class));
|
||||
// Doesn't match a method from Throwable
|
||||
assertFalse(rpc.matches(Exception.class.getMethod("getMessage", (Class[]) null), Exception.class));
|
||||
assertFalse(rpc.matches(Exception.class.getMethod("getMessage"), Exception.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+18
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class ComposablePointcutTests {
|
||||
public class ComposablePointcutTests {
|
||||
|
||||
public static MethodMatcher GETTER_METHOD_MATCHER = new StaticMethodMatcher() {
|
||||
@Override
|
||||
@@ -62,11 +62,12 @@ public final class ComposablePointcutTests {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchAll() throws NoSuchMethodException {
|
||||
Pointcut pc = new ComposablePointcut();
|
||||
assertTrue(pc.getClassFilter().matches(Object.class));
|
||||
assertTrue(pc.getMethodMatcher().matches(Object.class.getMethod("hashCode", (Class[]) null), Exception.class));
|
||||
assertTrue(pc.getMethodMatcher().matches(Object.class.getMethod("hashCode"), Exception.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,23 +94,23 @@ public final class ComposablePointcutTests {
|
||||
public void testUnionMethodMatcher() {
|
||||
// Matches the getAge() method in any class
|
||||
ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, GET_AGE_METHOD_MATCHER);
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
|
||||
pc.union(GETTER_METHOD_MATCHER);
|
||||
// Should now match all getter methods
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
|
||||
pc.union(ABSQUATULATE_METHOD_MATCHER);
|
||||
// Should now match absquatulate() as well
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
// But it doesn't match everything
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_SET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_SET_AGE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,9 +125,9 @@ public final class ComposablePointcutTests {
|
||||
assertTrue(pc.getMethodMatcher().matches(PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
pc.intersection(GET_AGE_METHOD_MATCHER);
|
||||
// Use the Pointcuts matches method
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,4 +154,5 @@ public final class ComposablePointcutTests {
|
||||
assertEquals(pc1, pc2);
|
||||
assertEquals(pc1.hashCode(), pc2.hashCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class MethodMatchersTests {
|
||||
public class MethodMatchersTests {
|
||||
|
||||
private final Method EXCEPTION_GETMESSAGE;
|
||||
|
||||
@@ -44,10 +44,10 @@ public final class MethodMatchersTests {
|
||||
|
||||
|
||||
public MethodMatchersTests() throws Exception {
|
||||
EXCEPTION_GETMESSAGE = Exception.class.getMethod("getMessage", (Class[]) null);
|
||||
ITESTBEAN_GETAGE = ITestBean.class.getMethod("getAge", (Class[]) null);
|
||||
ITESTBEAN_SETAGE = ITestBean.class.getMethod("setAge", new Class[] { int.class });
|
||||
IOTHER_ABSQUATULATE = IOther.class.getMethod("absquatulate", (Class[]) null);
|
||||
EXCEPTION_GETMESSAGE = Exception.class.getMethod("getMessage");
|
||||
ITESTBEAN_GETAGE = ITestBean.class.getMethod("getAge");
|
||||
ITESTBEAN_SETAGE = ITestBean.class.getMethod("setAge", int.class);
|
||||
IOTHER_ABSQUATULATE = IOther.class.getMethod("absquatulate");
|
||||
}
|
||||
|
||||
|
||||
@@ -82,12 +82,12 @@ public final class MethodMatchersTests {
|
||||
MethodMatcher intersection = MethodMatchers.intersection(mm1, mm2);
|
||||
assertTrue("Intersection is a dynamic matcher", intersection.isRuntime());
|
||||
assertTrue("2Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class));
|
||||
assertTrue("3Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Object[] { new Integer(5) }));
|
||||
assertTrue("3Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Integer(5)));
|
||||
// Knock out dynamic part
|
||||
intersection = MethodMatchers.intersection(intersection, new TestDynamicMethodMatcherWhichDoesNotMatch());
|
||||
assertTrue("Intersection is a dynamic matcher", intersection.isRuntime());
|
||||
assertTrue("2Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class));
|
||||
assertFalse("3 - not Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Object[] { new Integer(5) }));
|
||||
assertFalse("3 - not Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Integer(5)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,18 +125,20 @@ public final class MethodMatchersTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestDynamicMethodMatcherWhichMatches extends DynamicMethodMatcher {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestDynamicMethodMatcherWhichDoesNotMatch extends DynamicMethodMatcher {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class PointcutsTests {
|
||||
public class PointcutsTests {
|
||||
|
||||
public static Method TEST_BEAN_SET_AGE;
|
||||
public static Method TEST_BEAN_GET_AGE;
|
||||
@@ -39,10 +39,10 @@ public final class PointcutsTests {
|
||||
|
||||
static {
|
||||
try {
|
||||
TEST_BEAN_SET_AGE = TestBean.class.getMethod("setAge", new Class[] { int.class });
|
||||
TEST_BEAN_GET_AGE = TestBean.class.getMethod("getAge", (Class[]) null);
|
||||
TEST_BEAN_GET_NAME = TestBean.class.getMethod("getName", (Class[]) null);
|
||||
TEST_BEAN_ABSQUATULATE = TestBean.class.getMethod("absquatulate", (Class[]) null);
|
||||
TEST_BEAN_SET_AGE = TestBean.class.getMethod("setAge", int.class);
|
||||
TEST_BEAN_GET_AGE = TestBean.class.getMethod("getAge");
|
||||
TEST_BEAN_GET_NAME = TestBean.class.getMethod("getName");
|
||||
TEST_BEAN_ABSQUATULATE = TestBean.class.getMethod("absquatulate");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException("Shouldn't happen: error in test suite");
|
||||
@@ -125,22 +125,22 @@ public final class PointcutsTests {
|
||||
|
||||
@Test
|
||||
public void testTrue() {
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatches() {
|
||||
assertTrue(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,29 +149,29 @@ public final class PointcutsTests {
|
||||
@Test
|
||||
public void testUnionOfSettersAndGetters() {
|
||||
Pointcut union = Pointcuts.union(allClassGetterPointcut, allClassSetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionOfSpecificGetters() {
|
||||
Pointcut union = Pointcuts.union(allClassGetAgePointcut, allClassGetNamePointcut);
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
|
||||
// Union with all setters
|
||||
union = Pointcuts.union(union, allClassSetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,16 +180,16 @@ public final class PointcutsTests {
|
||||
*/
|
||||
@Test
|
||||
public void testUnionOfAllSettersAndSubclassSetters() {
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, MyTestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, MyTestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
|
||||
Pointcut union = Pointcuts.union(myTestBeanSetterPointcut, allClassGetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still doesn't match superclass setter
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, MyTestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, MyTestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,44 +198,44 @@ public final class PointcutsTests {
|
||||
*/
|
||||
@Test
|
||||
public void testIntersectionOfSpecificGettersAndSubclassGetters() {
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
|
||||
Pointcut intersection = Pointcuts.intersection(allClassGetAgePointcut, myTestBeanGetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
// Now intersection with MyTestBeanSubclass getters should eliminate MyTestBean target
|
||||
intersection = Pointcuts.intersection(intersection, myTestBeanSubclassGetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
// Now union with all TestBean methods
|
||||
Pointcut union = Pointcuts.union(intersection, allTestBeanMethodsPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, MyTestBean.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -245,9 +245,9 @@ public final class PointcutsTests {
|
||||
@Test
|
||||
public void testSimpleIntersection() {
|
||||
Pointcut intersection = Pointcuts.intersection(allClassGetterPointcut, allClassSetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -154,7 +154,8 @@ public class ThreadLocalTargetSourceTests {
|
||||
// try second time
|
||||
try {
|
||||
source.getTarget();
|
||||
} catch(NullPointerException ex) {
|
||||
}
|
||||
catch (NullPointerException ex) {
|
||||
fail("Should not throw NPE");
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -67,11 +67,22 @@ public abstract aspect AbstractCacheAspect extends CacheAspectSupport implements
|
||||
|
||||
CacheOperationInvoker aspectJInvoker = new CacheOperationInvoker() {
|
||||
public Object invoke() {
|
||||
return proceed(cachedObject);
|
||||
try {
|
||||
return proceed(cachedObject);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new ThrowableWrapper(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
||||
try {
|
||||
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
||||
}
|
||||
catch (CacheOperationInvoker.ThrowableWrapper th) {
|
||||
AnyThrow.throwUnchecked(th.getOriginal());
|
||||
return null; // never reached
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
/**
|
||||
* Utility to trick the compiler to throw a valid checked
|
||||
* exceptions within the interceptor.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class AnyThrow {
|
||||
|
||||
static void throwUnchecked(Throwable e) {
|
||||
AnyThrow.<RuntimeException>throwAny(e);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <E extends Throwable> void throwAny(Throwable e) throws E {
|
||||
throw (E) e;
|
||||
}
|
||||
}
|
||||
Vendored
+11
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,10 +24,11 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
|
||||
/**
|
||||
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
|
||||
* to enable AspectJ-based annotation-driven cache management.
|
||||
* {@code @Configuration} class that registers the Spring infrastructure beans
|
||||
* necessary to enable AspectJ-based annotation-driven cache management.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see org.springframework.cache.annotation.EnableCaching
|
||||
* @see org.springframework.cache.annotation.CachingConfigurationSelector
|
||||
@@ -39,12 +40,18 @@ public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationCacheAspect cacheAspect() {
|
||||
AnnotationCacheAspect cacheAspect = AnnotationCacheAspect.aspectOf();
|
||||
if (this.cacheManager != null) {
|
||||
if (this.cacheResolver != null) {
|
||||
cacheAspect.setCacheResolver(this.cacheResolver);
|
||||
}
|
||||
else if (this.cacheManager != null) {
|
||||
cacheAspect.setCacheManager(this.cacheManager);
|
||||
}
|
||||
if (this.keyGenerator != null) {
|
||||
cacheAspect.setKeyGenerator(this.keyGenerator);
|
||||
}
|
||||
if (this.errorHandler != null) {
|
||||
cacheAspect.setErrorHandler(this.errorHandler);
|
||||
}
|
||||
return cacheAspect;
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -109,16 +109,4 @@ public aspect JCacheCacheAspect extends JCacheAspectSupport {
|
||||
execution(@CacheRemoveAll * *(..));
|
||||
|
||||
|
||||
private static class AnyThrow {
|
||||
|
||||
private static void throwUnchecked(Throwable e) {
|
||||
AnyThrow.<RuntimeException>throwAny(e);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <E extends Throwable> void throwAny(Throwable e) throws E {
|
||||
throw (E)e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -29,8 +29,8 @@ import org.springframework.context.annotation.Role;
|
||||
* Configurable}.
|
||||
*
|
||||
* <p>This configuration class is automatically imported when using the
|
||||
* @{@link EnableSpringConfigured} annotation. See {@code @EnableSpringConfigured}'s
|
||||
* javadoc for complete usage details.
|
||||
* {@link EnableSpringConfigured @EnableSpringConfigured} annotation. See
|
||||
* {@code @EnableSpringConfigured}'s javadoc for complete usage details.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
|
||||
+2
@@ -36,7 +36,9 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Sam Brannen
|
||||
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
||||
|
||||
private final Expectations expectations = new Expectations();
|
||||
|
||||
+2
@@ -59,7 +59,9 @@ import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Sam Brannen
|
||||
* @see MockStaticEntityMethods
|
||||
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiredTypes("javax.persistence.Entity")
|
||||
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
||||
|
||||
|
||||
+2
@@ -29,7 +29,9 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
|
||||
*/
|
||||
@Deprecated
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface MockStaticEntityMethods {
|
||||
|
||||
+14
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,47 +17,49 @@
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
|
||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Abstract aspect that routes selected methods asynchronously.
|
||||
*
|
||||
* <p>This aspect needs to be injected with an implementation of
|
||||
* {@link Executor} to activate it for a specific thread pool.
|
||||
* Otherwise it will simply delegate all calls synchronously.
|
||||
* <p>This aspect needs to be injected with an implementation of a task-oriented
|
||||
* {@link java.util.concurrent.Executor} to activate it for a specific thread pool,
|
||||
* or with a {@link org.springframework.beans.factory.BeanFactory} for default
|
||||
* executor lookup. Otherwise it will simply delegate all calls synchronously.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.0.5
|
||||
* @see #setExecutor
|
||||
* @see #setBeanFactory
|
||||
* @see #getDefaultExecutor
|
||||
*/
|
||||
public abstract aspect AbstractAsyncExecutionAspect extends AsyncExecutionAspectSupport {
|
||||
|
||||
/**
|
||||
* Create an {@code AnnotationAsyncExecutionAspect} with a {@code null} default
|
||||
* executor, which should instead be set via {@code #aspectOf} and
|
||||
* {@link #setExecutor(Executor)}. The same applies for {@link #setExceptionHandler}
|
||||
* Create an {@code AnnotationAsyncExecutionAspect} with a {@code null}
|
||||
* default executor, which should instead be set via {@code #aspectOf} and
|
||||
* {@link #setExecutor}. The same applies for {@link #setExceptionHandler}.
|
||||
*/
|
||||
public AbstractAsyncExecutionAspect() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply around advice to methods matching the {@link #asyncMethod()} pointcut,
|
||||
* submit the actual calling of the method to the correct task executor and return
|
||||
* immediately to the caller.
|
||||
* @return {@link Future} if the original method returns {@code Future}; {@code null}
|
||||
* otherwise.
|
||||
* @return {@link Future} if the original method returns {@code Future};
|
||||
* {@code null} otherwise
|
||||
*/
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
Object around() : asyncMethod() {
|
||||
|
||||
+13
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,7 @@ package org.springframework.scheduling.aspectj;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
@@ -33,9 +33,17 @@ import org.springframework.scheduling.annotation.Async;
|
||||
* on the return type. If, however, a class marked with {@code @Async} contains a method
|
||||
* that violates this constraint, it produces only a warning.
|
||||
*
|
||||
* <p>This aspect needs to be injected with an implementation of a task-oriented
|
||||
* {@link java.util.concurrent.Executor} to activate it for a specific thread pool,
|
||||
* or with a {@link org.springframework.beans.factory.BeanFactory} for default
|
||||
* executor lookup. Otherwise it will simply delegate all calls synchronously.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
* @since 3.0.5
|
||||
* @see #setExecutor
|
||||
* @see #setBeanFactory
|
||||
* @see #getDefaultExecutor
|
||||
*/
|
||||
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
||||
|
||||
@@ -60,9 +68,9 @@ public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspec
|
||||
protected String getExecutorQualifier(Method method) {
|
||||
// Maintainer's note: changes made here should also be made in
|
||||
// AnnotationAsyncExecutionInterceptor#getExecutorQualifier
|
||||
Async async = AnnotationUtils.findAnnotation(method, Async.class);
|
||||
Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);
|
||||
if (async == null) {
|
||||
async = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Async.class);
|
||||
async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);
|
||||
}
|
||||
return (async != null ? async.value() : null);
|
||||
}
|
||||
@@ -74,7 +82,6 @@ public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspec
|
||||
|
||||
declare warning:
|
||||
execution(!(void || Future+) (@Async *).*(..)):
|
||||
"Methods in a class marked with @Async that do not return void or Future will " +
|
||||
"be routed synchronously";
|
||||
"Methods in a class marked with @Async that do not return void or Future will be routed synchronously";
|
||||
|
||||
}
|
||||
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.CacheTestUtils;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.config.AnnotatedClassCacheableService;
|
||||
import org.springframework.cache.config.CacheableService;
|
||||
import org.springframework.cache.config.DefaultCacheableService;
|
||||
import org.springframework.cache.config.SomeCustomKeyGenerator;
|
||||
import org.springframework.cache.config.SomeKeyGenerator;
|
||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.cache.interceptor.NamedCacheResolver;
|
||||
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
||||
import org.springframework.cache.support.NoOpCacheManager;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class AspectJEnableCachingIsolatedTests {
|
||||
|
||||
private ConfigurableApplicationContext ctx;
|
||||
|
||||
|
||||
private void load(Class<?>... config) {
|
||||
this.ctx = new AnnotationConfigApplicationContext(config);
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.ctx != null) {
|
||||
this.ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testKeyStrategy() {
|
||||
load(EnableCachingConfig.class);
|
||||
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
|
||||
assertSame(this.ctx.getBean("keyGenerator", KeyGenerator.class), aspect.getKeyGenerator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheErrorHandler() {
|
||||
load(EnableCachingConfig.class);
|
||||
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
|
||||
assertSame(this.ctx.getBean("errorHandler", CacheErrorHandler.class), aspect.getErrorHandler());
|
||||
}
|
||||
|
||||
|
||||
// --- local tests -------
|
||||
|
||||
@Test
|
||||
public void singleCacheManagerBean() {
|
||||
load(SingleCacheManagerConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCacheManagerBeans() {
|
||||
try {
|
||||
load(MultiCacheManagerConfig.class);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().contains("bean of type CacheManager"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCacheManagerBeans_implementsCachingConfigurer() {
|
||||
load(MultiCacheManagerConfigurer.class); // does not throw
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCachingConfigurers() {
|
||||
try {
|
||||
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable root = ex.getRootCause();
|
||||
assertTrue(root instanceof IllegalStateException);
|
||||
assertTrue(ex.getMessage().contains("implementations of CachingConfigurer"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noCacheManagerBeans() {
|
||||
try {
|
||||
load(EmptyConfig.class);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().contains("No bean of type CacheManager"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("AspectJ has some sort of caching that makes this one fail")
|
||||
public void emptyConfigSupport() {
|
||||
load(EmptyConfigSupportConfig.class);
|
||||
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
|
||||
assertNotNull(aspect.getCacheResolver());
|
||||
assertEquals(SimpleCacheResolver.class, aspect.getCacheResolver().getClass());
|
||||
assertSame(this.ctx.getBean(CacheManager.class),
|
||||
((SimpleCacheResolver) aspect.getCacheResolver()).getCacheManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bothSetOnlyResolverIsUsed() {
|
||||
load(FullCachingConfig.class);
|
||||
|
||||
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
|
||||
assertSame(this.ctx.getBean("cacheResolver"), aspect.getCacheResolver());
|
||||
assertSame(this.ctx.getBean("keyGenerator"), aspect.getKeyGenerator());
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class EnableCachingConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
return CacheTestUtils.createSimpleCacheManager("testCache", "primary", "secondary");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheableService<?> service() {
|
||||
return new DefaultCacheableService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheableService<?> classService() {
|
||||
return new AnnotatedClassCacheableService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new SomeKeyGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheErrorHandler errorHandler() {
|
||||
return new SimpleCacheErrorHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeyGenerator customKeyGenerator() {
|
||||
return new SomeCustomKeyGenerator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager customCacheManager() {
|
||||
return CacheTestUtils.createSimpleCacheManager("testCache");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class EmptyConfig {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class SingleCacheManagerConfig {
|
||||
|
||||
@Bean
|
||||
public CacheManager cm1() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class MultiCacheManagerConfig {
|
||||
|
||||
@Bean
|
||||
public CacheManager cm1() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager cm2() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class MultiCacheManagerConfigurer extends CachingConfigurerSupport {
|
||||
|
||||
@Bean
|
||||
public CacheManager cm1() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager cm2() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheManager cacheManager() {
|
||||
return cm1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class EmptyConfigSupportConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Bean
|
||||
public CacheManager cm() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class FullCachingConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
return new NoOpCacheManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new SomeKeyGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheResolver cacheResolver() {
|
||||
return new NamedCacheResolver(cacheManager(), "foo");
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.CacheTestUtils;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.config.AbstractCacheAnnotationTests;
|
||||
import org.springframework.cache.config.AnnotatedClassCacheableService;
|
||||
import org.springframework.cache.config.CacheableService;
|
||||
import org.springframework.cache.config.DefaultCacheableService;
|
||||
import org.springframework.cache.config.SomeCustomKeyGenerator;
|
||||
import org.springframework.cache.config.SomeKeyGenerator;
|
||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class AspectJEnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
|
||||
@Override
|
||||
protected ConfigurableApplicationContext getApplicationContext() {
|
||||
return new AnnotationConfigApplicationContext(EnableCachingConfig.class);
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
static class EnableCachingConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
return CacheTestUtils.createSimpleCacheManager("testCache", "primary", "secondary");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheableService<?> service() {
|
||||
return new DefaultCacheableService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheableService<?> classService() {
|
||||
return new AnnotatedClassCacheableService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new SomeKeyGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public CacheErrorHandler errorHandler() {
|
||||
return new SimpleCacheErrorHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeyGenerator customKeyGenerator() {
|
||||
return new SomeCustomKeyGenerator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager customCacheManager() {
|
||||
return CacheTestUtils.createSimpleCacheManager("testCache");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+33
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.cache.annotation.Caching;
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Cacheable("testCache")
|
||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||
@@ -44,11 +45,28 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Object cacheSync(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Object cacheSyncNull(Object arg1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object conditional(int field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object conditionalSync(int field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unless(int arg) {
|
||||
return arg;
|
||||
@@ -168,6 +186,18 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Object throwCheckedSync(Object arg1) throws Exception {
|
||||
throw new IOException(arg1.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Object throwUncheckedSync(Object arg1) {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Override
|
||||
@@ -177,7 +207,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||
}
|
||||
|
||||
@Override
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0") })
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#a0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
|
||||
public Object multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
@@ -189,7 +219,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||
}
|
||||
|
||||
@Override
|
||||
@Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
@Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#a0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
+11
@@ -21,6 +21,7 @@ package org.springframework.cache.config;
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public interface CacheableService<T> {
|
||||
|
||||
@@ -28,6 +29,10 @@ public interface CacheableService<T> {
|
||||
|
||||
T cacheNull(Object arg1);
|
||||
|
||||
T cacheSync(Object arg1);
|
||||
|
||||
T cacheSyncNull(Object arg1);
|
||||
|
||||
void invalidate(Object arg1);
|
||||
|
||||
void evictEarly(Object arg1);
|
||||
@@ -42,6 +47,8 @@ public interface CacheableService<T> {
|
||||
|
||||
T conditional(int field);
|
||||
|
||||
T conditionalSync(int field);
|
||||
|
||||
T unless(int arg);
|
||||
|
||||
T key(Object arg1, Object arg2);
|
||||
@@ -72,6 +79,10 @@ public interface CacheableService<T> {
|
||||
|
||||
T throwUnchecked(Object arg1);
|
||||
|
||||
T throwCheckedSync(Object arg1) throws Exception;
|
||||
|
||||
T throwUncheckedSync(Object arg1);
|
||||
|
||||
// multi annotations
|
||||
T multiCache(Object arg1);
|
||||
|
||||
|
||||
+35
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,7 @@ import org.springframework.cache.annotation.Caching;
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class DefaultCacheableService implements CacheableService<Long> {
|
||||
|
||||
@@ -47,6 +48,18 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Long cacheSync(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Long cacheSyncNull(Object arg1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict("testCache")
|
||||
public void invalidate(Object arg1) {
|
||||
@@ -81,11 +94,17 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", condition = "#classField == 3")
|
||||
@Cacheable(cacheNames = "testCache", condition = "#p0 == 3")
|
||||
public Long conditional(int classField) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true, condition = "#p0 == 3")
|
||||
public Long conditionalSync(int field) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", unless = "#result > 10")
|
||||
public Long unless(int arg) {
|
||||
@@ -99,7 +118,7 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("testCache")
|
||||
@Cacheable(cacheNames = "testCache")
|
||||
public Long varArgsKey(Object... args) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
@@ -176,6 +195,18 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Long throwCheckedSync(Object arg1) throws Exception {
|
||||
throw new IOException(arg1.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "testCache", sync = true)
|
||||
public Long throwUncheckedSync(Object arg1) {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Override
|
||||
@@ -185,8 +216,7 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
//FIXME @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0") })
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
|
||||
public Long multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,7 @@ import org.springframework.cache.interceptor.KeyGenerator;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
final class SomeCustomKeyGenerator implements KeyGenerator {
|
||||
public final class SomeCustomKeyGenerator implements KeyGenerator {
|
||||
|
||||
@Override
|
||||
public Object generate(Object target, Method method, Object... params) {
|
||||
|
||||
+2
-1
@@ -210,7 +210,8 @@ public class AnnotationAsyncExecutionAspectTests {
|
||||
public synchronized void waitForCompletion() {
|
||||
try {
|
||||
wait(WAIT_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -31,7 +31,6 @@ import groovy.lang.GroovyObjectSupport;
|
||||
import groovy.lang.GroovyShell;
|
||||
import groovy.lang.GroovySystem;
|
||||
import groovy.lang.MetaClass;
|
||||
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
|
||||
import org.codehaus.groovy.runtime.InvokerHelper;
|
||||
|
||||
@@ -337,8 +336,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("Namespace definition must supply a non-null URI");
|
||||
}
|
||||
NamespaceHandler namespaceHandler = this.groovyDslXmlBeanDefinitionReader.getNamespaceHandlerResolver().resolve(
|
||||
uri);
|
||||
NamespaceHandler namespaceHandler =
|
||||
this.groovyDslXmlBeanDefinitionReader.getNamespaceHandlerResolver().resolve(uri);
|
||||
if (namespaceHandler == null) {
|
||||
throw new BeanDefinitionParsingException(new Problem("No namespace handler found for URI: " + uri,
|
||||
new Location(new DescriptiveResource(("Groovy")))));
|
||||
@@ -375,7 +374,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
throw new IllegalArgumentException("Argument to ref() is not a valid bean or was not found");
|
||||
|
||||
if (args[0] instanceof RuntimeBeanReference) {
|
||||
refName = ((RuntimeBeanReference)args[0]).getBeanName();
|
||||
refName = ((RuntimeBeanReference) args[0]).getBeanName();
|
||||
}
|
||||
else {
|
||||
refName = args[0].toString();
|
||||
@@ -388,7 +387,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
return new RuntimeBeanReference(refName, parentRef);
|
||||
}
|
||||
else if (this.namespaces.containsKey(name) && args.length > 0 && (args[0] instanceof Closure)) {
|
||||
else if (this.namespaces.containsKey(name) && args.length > 0 && args[0] instanceof Closure) {
|
||||
GroovyDynamicElementReader reader = createDynamicElementReader(name);
|
||||
reader.invokeMethod("doCall", args);
|
||||
}
|
||||
@@ -396,7 +395,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
// abstract bean definition
|
||||
return invokeBeanDefiningMethod(name, args);
|
||||
}
|
||||
else if (args.length > 0 && (args[0] instanceof Class || args[0] instanceof RuntimeBeanReference || args[0] instanceof Map)) {
|
||||
else if (args.length > 0 &&
|
||||
(args[0] instanceof Class || args[0] instanceof RuntimeBeanReference || args[0] instanceof Map)) {
|
||||
return invokeBeanDefiningMethod(name, args);
|
||||
}
|
||||
else if (args.length > 1 && args[args.length -1] instanceof Closure) {
|
||||
|
||||
+27
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -87,14 +87,14 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
|
||||
|
||||
/** The wrapped object */
|
||||
private Object object;
|
||||
Object wrappedObject;
|
||||
|
||||
private String nestedPath = "";
|
||||
|
||||
private Object rootObject;
|
||||
Object rootObject;
|
||||
|
||||
/**
|
||||
* Map with cached nested Accessors: nested path -> Accessor instance.
|
||||
@@ -204,23 +204,23 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
public void setWrappedInstance(Object object, String nestedPath, Object rootObject) {
|
||||
Assert.notNull(object, "Target object must not be null");
|
||||
if (object.getClass() == javaUtilOptionalClass) {
|
||||
this.object = OptionalUnwrapper.unwrap(object);
|
||||
this.wrappedObject = OptionalUnwrapper.unwrap(object);
|
||||
}
|
||||
else {
|
||||
this.object = object;
|
||||
this.wrappedObject = object;
|
||||
}
|
||||
this.nestedPath = (nestedPath != null ? nestedPath : "");
|
||||
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : this.object);
|
||||
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : this.wrappedObject);
|
||||
this.nestedPropertyAccessors = null;
|
||||
this.typeConverterDelegate = new TypeConverterDelegate(this, this.object);
|
||||
this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
|
||||
}
|
||||
|
||||
public final Object getWrappedInstance() {
|
||||
return this.object;
|
||||
return this.wrappedObject;
|
||||
}
|
||||
|
||||
public final Class<?> getWrappedClass() {
|
||||
return (this.object != null ? this.object.getClass() : null);
|
||||
return (this.wrappedObject != null ? this.wrappedObject.getClass() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +303,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
catch (NotReadablePropertyException ex) {
|
||||
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot access indexed value in property referenced " +
|
||||
"in indexed property path '" + propertyName + "'", ex);
|
||||
"in indexed property path '" + propertyName + "'", ex);
|
||||
}
|
||||
// Set value for last key.
|
||||
String key = tokens.keys[tokens.keys.length - 1];
|
||||
@@ -318,7 +318,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
else {
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot access indexed value in property referenced " +
|
||||
"in indexed property path '" + propertyName + "': returned null");
|
||||
"in indexed property path '" + propertyName + "': returned null");
|
||||
}
|
||||
}
|
||||
if (propValue.getClass().isArray()) {
|
||||
@@ -367,8 +367,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
catch (NullPointerException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot set element with index " + index + " in List of size " +
|
||||
size + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
size + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
}
|
||||
}
|
||||
list.add(convertedValue);
|
||||
@@ -405,7 +405,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
else {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Property referenced in indexed property path '" + propertyName +
|
||||
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
|
||||
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
ph.setValue(object, valueToApply);
|
||||
ph.setValue(this.wrappedObject, valueToApply);
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
throw ex;
|
||||
@@ -590,7 +590,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new ConversionNotSupportedException(pce, requiredType, ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
catch (Throwable ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new TypeMismatchException(pce, requiredType, ex);
|
||||
@@ -800,7 +800,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
|
||||
/**
|
||||
* Recursively navigate to return a property accessor for the nested property path.
|
||||
* @param propertyPath property property path, which may be nested
|
||||
* @param propertyPath property path, which may be nested
|
||||
* @return a property accessor for the target bean
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
@@ -914,11 +914,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
return BeanUtils.instantiate(type);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// TODO: Root cause exception context is lost here; just exception message preserved.
|
||||
// Should we throw another exception type that preserves context instead?
|
||||
catch (Throwable ex) {
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name,
|
||||
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex);
|
||||
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -942,7 +940,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
actualName = propertyName.substring(0, keyStart);
|
||||
}
|
||||
String key = propertyName.substring(keyStart + PROPERTY_KEY_PREFIX.length(), keyEnd);
|
||||
if ((key.startsWith("'") && key.endsWith("'")) || (key.startsWith("\"") && key.endsWith("\""))) {
|
||||
if (key.length() > 1 && (key.startsWith("'") && key.endsWith("'")) ||
|
||||
(key.startsWith("\"") && key.endsWith("\""))) {
|
||||
key = key.substring(1, key.length() - 1);
|
||||
}
|
||||
keys.add(key);
|
||||
@@ -953,10 +952,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
tokens.actualName = (actualName != null ? actualName : propertyName);
|
||||
tokens.canonicalName = tokens.actualName;
|
||||
if (!keys.isEmpty()) {
|
||||
tokens.canonicalName +=
|
||||
PROPERTY_KEY_PREFIX +
|
||||
StringUtils.collectionToDelimitedString(keys, PROPERTY_KEY_SUFFIX + PROPERTY_KEY_PREFIX) +
|
||||
PROPERTY_KEY_SUFFIX;
|
||||
tokens.canonicalName += PROPERTY_KEY_PREFIX +
|
||||
StringUtils.collectionToDelimitedString(keys, PROPERTY_KEY_SUFFIX + PROPERTY_KEY_PREFIX) +
|
||||
PROPERTY_KEY_SUFFIX;
|
||||
tokens.keys = StringUtils.toStringArray(keys);
|
||||
}
|
||||
return tokens;
|
||||
@@ -965,8 +963,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(getClass().getName());
|
||||
if (this.object != null) {
|
||||
sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.object)).append("]");
|
||||
if (this.wrappedObject != null) {
|
||||
sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.wrappedObject)).append("]");
|
||||
}
|
||||
else {
|
||||
sb.append(": no wrapped object set");
|
||||
|
||||
@@ -148,7 +148,7 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyAccessException if the property was valid but the
|
||||
* accessor method failed or a type mismatch occured
|
||||
* accessor method failed or a type mismatch occurred
|
||||
*/
|
||||
@Override
|
||||
public abstract void setPropertyValue(String propertyName, Object value) throws BeansException;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user