mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
650 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ffc44db78 | |||
| 25101fb034 | |||
| cb44ae62e9 | |||
| 01fb4dbeba | |||
| 07fadae27d | |||
| 2b77c08e09 | |||
| cb2b141d31 | |||
| 3b92d45984 | |||
| 1195b3a0b0 | |||
| 56721669d1 | |||
| e87e03c539 | |||
| 194cebd730 | |||
| 7418c4b7b7 | |||
| ad42010785 | |||
| 10f6a22315 | |||
| c970c318f4 | |||
| 834032df1f | |||
| 5efa4ad442 | |||
| 7ef3257b03 | |||
| 0172424635 | |||
| 994ec708fc | |||
| da15fe4c94 | |||
| a1d134b086 | |||
| 3c85c263d2 | |||
| 7b3f53de50 | |||
| ec7425c1f4 | |||
| ef05eb3729 | |||
| 8ac39a50fe | |||
| d82cb15439 | |||
| 8c1d06e0c4 | |||
| 01892c6524 | |||
| 9776929a9d | |||
| 4337d8465c | |||
| 8f0ad73bfd | |||
| 3714d0e401 | |||
| 227d85a6b4 | |||
| a1320cd450 | |||
| c7f2f50c15 | |||
| 396fb0cd51 | |||
| 5328184f3a | |||
| 1e19e51c9c | |||
| 69aed83504 | |||
| 0978cc629a | |||
| 0c825621b8 | |||
| e7b0b65244 | |||
| e9caee1b6e | |||
| 622d0831a3 | |||
| 56dbe06d9b | |||
| 11f6c4e7ab | |||
| d46091565b | |||
| 42216b77df | |||
| 43faa439ab | |||
| 1f701d9bad | |||
| 73e1f24ac1 | |||
| 86f9716fef | |||
| 80701082cd | |||
| 3612990344 | |||
| dea2029e94 | |||
| 77d6f8bc00 | |||
| 23006d417b | |||
| d8dafbc49d | |||
| cc4a1af091 | |||
| fd70a9e95d | |||
| 298cb22bfe | |||
| 4ed645e710 | |||
| 7c47f554c0 | |||
| 642d47ef8d | |||
| 42e492ef2a | |||
| 4fb5d59c64 | |||
| e6324bd578 | |||
| 45a9227047 | |||
| f1af8a6ae9 | |||
| c4d7e6ff46 | |||
| 922d5d271a | |||
| 05e3f271b6 | |||
| a7cce64e5d | |||
| a0544e78ea | |||
| c92dccea1b | |||
| 9ec96f6141 | |||
| 135682e073 | |||
| 6a0377b1a2 | |||
| 8c3a05bbcf | |||
| 684e695b08 | |||
| 8130bf505f | |||
| 9beca06404 | |||
| ae75db2657 | |||
| 4cc831238c | |||
| 41835ba5a4 | |||
| de0b5bc5a1 | |||
| b29723623b | |||
| 2ee231dee2 | |||
| b56dbd2aa8 | |||
| c9b27af64f | |||
| 9139cb85bd | |||
| 367fbbb981 | |||
| 1b1ba47912 | |||
| 041bff4e56 | |||
| bc5a10c70d | |||
| 3d31750acc | |||
| c22a483c3d | |||
| 238354a081 | |||
| 51b1306d70 | |||
| 7206a23d33 | |||
| 83996b12cc | |||
| 0fd6c100a6 | |||
| 0819a9fcc9 | |||
| 0b580d194d | |||
| 500b54b86f | |||
| 942400ae47 | |||
| b92d249f45 | |||
| 204a7fe91f | |||
| 42d3bc47c9 | |||
| 94fcb37d30 | |||
| ba9325446c | |||
| 5338d8b5e9 | |||
| 1b0be5862d | |||
| 48af36c6fa | |||
| bd4e915abf | |||
| c419ea7ba7 | |||
| 66292cd7a1 | |||
| 6eec1acdac | |||
| bc32d513d9 | |||
| 3851b291da | |||
| 2b1f229998 | |||
| fc5e3c335f | |||
| daf9a82e8c | |||
| b019f30a15 | |||
| d5b5e894c9 | |||
| 2899652d8e | |||
| 560a504a83 | |||
| 79f79e9306 | |||
| bd2640a9d6 | |||
| 6825287360 | |||
| 737d77a739 | |||
| 1f13516528 | |||
| 6bb3ad793e | |||
| c73cff8bad | |||
| e592634290 | |||
| b25637e8ad | |||
| 0c347769a2 | |||
| 2497d4285f | |||
| 32238cc996 | |||
| d80dd50c9d | |||
| bdf120f1ef | |||
| e781d21097 | |||
| 8cef13cc30 | |||
| 2214ff8ce0 | |||
| 411539ffef | |||
| 11aa901634 | |||
| 6e51370490 | |||
| bcd2b9a8a7 | |||
| 17dd7785f6 | |||
| 21f9d05bd9 | |||
| 19911af30a | |||
| 6acb091c4e | |||
| 99ed01e3f7 | |||
| 2657757566 | |||
| e1f51b4bf8 | |||
| f2f84bfa7a | |||
| 6d67bdf04f | |||
| 97c8628bd6 | |||
| 990a9c74b9 | |||
| b815accca9 | |||
| 4e8d6bea4d | |||
| 079ca80854 | |||
| 412aa06d86 | |||
| d5b3e65718 | |||
| a4679b87b9 | |||
| fbf8e37f94 | |||
| 8c3cab7ead | |||
| 0015fd6734 | |||
| b077e4cd85 | |||
| 0a0299693b | |||
| 41bdde5d6b | |||
| 2e2d662158 | |||
| 68934f1b79 | |||
| f781c459b4 | |||
| 5628c8cd63 | |||
| 0f6038af70 | |||
| 3eb2c5e22f | |||
| 3f722a9c7f | |||
| acbbf61be8 | |||
| 154f0c71c9 | |||
| 7be7e5beb4 | |||
| 37504e75e9 | |||
| b89b37729c | |||
| 141c79bc8f | |||
| 885a5048c1 | |||
| e981bf34b3 | |||
| 44239b2d7b | |||
| a00c483927 | |||
| 96ffa14141 | |||
| 9f632cf0c1 | |||
| a9dec6a4af | |||
| 9c2fd0bd05 | |||
| 6e936a4081 | |||
| b2d337c527 | |||
| 24cef14683 | |||
| bb4e802af5 | |||
| b01adadf60 | |||
| 9c11887fe8 | |||
| 4503260282 | |||
| d91b66a04c | |||
| d1e6883d5d | |||
| 5170f3f594 | |||
| a4d546a9d6 | |||
| fc9650a9a6 | |||
| 82fa3f3fc1 | |||
| 1fb33fbd3c | |||
| b6dae6acba | |||
| a3cd8e11b0 | |||
| f50c2caf59 | |||
| 0aa3205e38 | |||
| 5b910a87c3 | |||
| 9ebd3ee1fe | |||
| 3f01af6f7c | |||
| f329748657 | |||
| d12996a6a8 | |||
| d04c5f8b2c | |||
| 41247d49ba | |||
| 16c8676e5b | |||
| d7f1813cd7 | |||
| ada255d584 | |||
| 7aef0c78a0 | |||
| 188a5a086b | |||
| 705cf09ad7 | |||
| 449377908f | |||
| b1fef925af | |||
| 9287c15583 | |||
| 9a4a593c7f | |||
| c840ba9989 | |||
| 3924947773 | |||
| 9d70d2023c | |||
| 82835b99ec | |||
| a3f3a136c4 | |||
| a2ff03074f | |||
| a3fcfc5d2a | |||
| 1247e4a0e8 | |||
| 1676470729 | |||
| 4726663f81 | |||
| 86af93a504 | |||
| efe933ad83 | |||
| 5429c7afeb | |||
| 73eefeac5f | |||
| 1a50732daa | |||
| 1c82ba425b | |||
| 946e5c9bbf | |||
| af4d68b1a5 | |||
| a40cc8bbe0 | |||
| 6e640c806f | |||
| e66e34766e | |||
| 5644a7aebb | |||
| 7af726480f | |||
| 51fb49be34 | |||
| c524849774 | |||
| f2eb67373a | |||
| cf988f81b5 | |||
| 417e7e03d4 | |||
| 8d86d61f9f | |||
| fb4363e4e0 | |||
| 1ec6843913 | |||
| cff57ca1fe | |||
| 784d72cc56 | |||
| 4480269432 | |||
| 9a1323aad5 | |||
| eec6ec8f44 | |||
| 6946fe2f74 | |||
| db9e0b0ccb | |||
| aaa2d21058 | |||
| b8b854db8c | |||
| 95110d8257 | |||
| cfc3522641 | |||
| 621295dbd8 | |||
| 07769ddcc6 | |||
| c748870853 | |||
| f7ec92c647 | |||
| bd91dc70d5 | |||
| 7bee3d1574 | |||
| dff9924a0c | |||
| bfb2ce6e2a | |||
| 76eb5e6e2c | |||
| 43f595f80e | |||
| 6f131ba1c4 | |||
| d18fbab7a8 | |||
| a4d0af802a | |||
| db3d537e72 | |||
| a0727191e1 | |||
| 702a05e926 | |||
| 0df6d60fea | |||
| 5ab1097b43 | |||
| d77ecb26a9 | |||
| 6d4b286b1a | |||
| 970afbc614 | |||
| f13c43bafe | |||
| 23211c784e | |||
| a2ff139edd | |||
| 424e28bc35 | |||
| 4952336419 | |||
| babcbd0d2b | |||
| c45b106d95 | |||
| b7d1bbb991 | |||
| 603a1dd319 | |||
| 6b978cb5dc | |||
| b79548d12e | |||
| f9e11593a6 | |||
| 57ac32b808 | |||
| 2eee56d0e2 | |||
| a271a0a2bf | |||
| 69af56c4e9 | |||
| a924677b49 | |||
| 7e647ab1d8 | |||
| abd79d43af | |||
| 431ec906c4 | |||
| 1d96f6a266 | |||
| e5ae2cb0fe | |||
| 33fcba55d1 | |||
| 3ed8813bbf | |||
| cd835b3124 | |||
| 7b6293fa05 | |||
| a6e48811c0 | |||
| 4a608e97dc | |||
| 74c2df43cc | |||
| 2934a823ed | |||
| 379d9167d9 | |||
| cd7e5f61f0 | |||
| 06b6a4be16 | |||
| e9cd37a4ee | |||
| f3f19504c6 | |||
| 72b2dda17f | |||
| 0af09e076b | |||
| 7f365942a5 | |||
| 1b63c31722 | |||
| 37e35b37d4 | |||
| a9d458f5fc | |||
| e176c4e799 | |||
| 9dc64f5f5f | |||
| ca2b412905 | |||
| 690e219fe8 | |||
| fbb3c5cce7 | |||
| 66a67ec807 | |||
| 69c330d905 | |||
| 8c47c7c797 | |||
| 21f2863d8e | |||
| 83bfee9201 | |||
| 50b9542402 | |||
| 2a34c0ea70 | |||
| fec89af239 | |||
| 6641dbc852 | |||
| b9f7b0d955 | |||
| 809851c0fe | |||
| 5b1b20c8c0 | |||
| 66138f0dce | |||
| e73e489fd8 | |||
| cdd48ddd7f | |||
| c4de445822 | |||
| 94a42a3086 | |||
| fad7243733 | |||
| d49a7a105d | |||
| 24bd0148d5 | |||
| fee8abfa5f | |||
| d05803aa04 | |||
| d55c5b30d7 | |||
| ec9de943ee | |||
| 1c1bc41e24 | |||
| eb11c6fa23 | |||
| 7d7ed88739 | |||
| e899397438 | |||
| b2d8180f82 | |||
| 9990bd2ea8 | |||
| 92b2c45281 | |||
| 1cd8871d7f | |||
| 1c5b95db0b | |||
| 30c7940483 | |||
| e78aa6b8f8 | |||
| f5d9babfd2 | |||
| a0af552d0f | |||
| cf61545f41 | |||
| 8a04910bdd | |||
| b7e1553c9d | |||
| 392895e256 | |||
| ca7fb23432 | |||
| f83bb7183e | |||
| 1745a3f25d | |||
| e417318915 | |||
| 200b33b26a | |||
| d3087537d5 | |||
| 444c8185b6 | |||
| 2533ba5253 | |||
| e44b08f1fc | |||
| 3303a68436 | |||
| 4e76a4780c | |||
| c083b95ce1 | |||
| 92cc006b2c | |||
| dfb7ca733a | |||
| 86f2ebec1b | |||
| 7ad60d385b | |||
| 4b9c3fa739 | |||
| a6bede22c1 | |||
| a0c00362c3 | |||
| 8057fb38b2 | |||
| ba94a1216c | |||
| 97cc89630d | |||
| b34778d220 | |||
| c45be0bf27 | |||
| 10eb5bde59 | |||
| 52084ed954 | |||
| b9ef5416b9 | |||
| 852e904b08 | |||
| bedf2de614 | |||
| 10c5f85a9f | |||
| db9190e0e6 | |||
| 1404dd768f | |||
| 3e4ce9a348 | |||
| 7116e5f755 | |||
| 2dbceb9053 | |||
| 84b1efa4b8 | |||
| 6aa522b3c1 | |||
| b322cbd625 | |||
| e33e7d7681 | |||
| 61d893257e | |||
| e02d3f32b4 | |||
| f89bd47188 | |||
| d022fcf32f | |||
| e028ef8170 | |||
| 6c631e3d5c | |||
| 9ad5a8ead0 | |||
| 6e4fcb69f0 | |||
| 392ad09990 | |||
| 21cb9e8bff | |||
| c83f6adc24 | |||
| d9da663f6d | |||
| c04400890f | |||
| 00651a3e38 | |||
| d7fab85f51 | |||
| bf00db3c6c | |||
| f5d36aa47a | |||
| 9795883d91 | |||
| 214bc407b4 | |||
| ad5072a43c | |||
| 687c3985d5 | |||
| 6f04c7b60e | |||
| a532c527dd | |||
| 6e7be76278 | |||
| 1061bcdba2 | |||
| a5a4960859 | |||
| 2342f5f48a | |||
| 87399aedf7 | |||
| 2a74f20c99 | |||
| f5d7161d6b | |||
| 82e64af5a5 | |||
| bbe74635eb | |||
| c1617d3c52 | |||
| 9dfef59af2 | |||
| 4179ea6f22 | |||
| e58e33606a | |||
| 1eef0beda1 | |||
| ec225b07fa | |||
| 051de3f179 | |||
| 5f587faffa | |||
| ec97089dff | |||
| 9c8a8d82b9 | |||
| a6daed1b71 | |||
| e9065402f2 | |||
| fe9f29f031 | |||
| 0556fdecaa | |||
| e4a3d5bf66 | |||
| 09080bcbf5 | |||
| 8b8b59bf80 | |||
| 28df426798 | |||
| c27419f74d | |||
| 845cb715e7 | |||
| d5fed34642 | |||
| f010368a66 | |||
| f4bdc0284e | |||
| 801c8ed8ac | |||
| cd6085a310 | |||
| b8c12a3aa1 | |||
| 6e3ed6038b | |||
| 07b3e92bae | |||
| 3ec4538981 | |||
| 3c84863271 | |||
| c2f6a98c90 | |||
| 49d65d5c41 | |||
| 29885e2b9f | |||
| 3b0f14fd2e | |||
| bd277819fd | |||
| 16d125ce76 | |||
| dccc78146a | |||
| 74f64c4e3b | |||
| dde79a9b65 | |||
| 4dfecde694 | |||
| dc26968224 | |||
| ef10ac6b29 | |||
| 3295034839 | |||
| b50ad1b9aa | |||
| 49356b2c0f | |||
| 852718ec0e | |||
| 0db3f2b4de | |||
| f37e0c6a1b | |||
| 31316a11fd | |||
| b2a0978c12 | |||
| af3dc5d440 | |||
| 8473f71a42 | |||
| b61d0584a9 | |||
| 3bd96a665f | |||
| 07d2c08f48 | |||
| fe6962051e | |||
| a958633b7a | |||
| ed3b7cd10f | |||
| 4d1d60ac42 | |||
| f7a014d7dc | |||
| 93f201a414 | |||
| 078543ce67 | |||
| 7dbb40ffa0 | |||
| c6cc6705ef | |||
| ae1d15c8f4 | |||
| 91b609817e | |||
| dd011c991c | |||
| d616c6632d | |||
| 94c91c9e9c | |||
| b6ff12d2f5 | |||
| b1d84067cd | |||
| c19fc9d53f | |||
| 899761f0a8 | |||
| f88759c3c9 | |||
| 59ecedea46 | |||
| 0d699840ad | |||
| 3cc0db5fc3 | |||
| 4f0f29880f | |||
| 4b211fb18c | |||
| a93af329fc | |||
| 75f394ca85 | |||
| e797398b10 | |||
| 613b05d814 | |||
| 30d556b9ef | |||
| 71ecca7443 | |||
| 8c2852607d | |||
| c5694506ae | |||
| 3fd89c3ac1 | |||
| 9d7849c539 | |||
| 939c76c4a5 | |||
| 40bf83c9e5 | |||
| c368ce8223 | |||
| a404bf5a94 | |||
| 4044f4c30f | |||
| a2bb59f1b8 | |||
| 33195da64f | |||
| 3aae0fc91b | |||
| 670b9fd60b | |||
| d550d344d5 | |||
| 88249b2d9a | |||
| f55b48f4b4 | |||
| c2363a6ef9 | |||
| a06deac5db | |||
| cdfdc340d2 | |||
| e02ccc9374 | |||
| 689adb4bd0 | |||
| 7bd6b8d279 | |||
| 141470ff58 | |||
| e20bff9c64 | |||
| 278c6d5cdb | |||
| 25165f552d | |||
| e365e0221a | |||
| d62202f464 | |||
| bcdc2503fa | |||
| 61311248bf | |||
| 603d7e93b9 | |||
| e34c800467 | |||
| c6b87b3ef4 | |||
| 9b6476c0a1 | |||
| 591ab8a00a | |||
| 8f369ffed5 | |||
| 3a73533b1c | |||
| d8c420ab75 | |||
| 1f3e52d932 | |||
| 79cf6b4353 | |||
| 97d84d9ab8 | |||
| ae4160e131 | |||
| a033660425 | |||
| 7bc8035989 | |||
| 42aeb6cd93 | |||
| c4e1e4ee1e | |||
| a8d953afa4 | |||
| bb941b6180 | |||
| c4f4fbc003 | |||
| 00c5dbf11a | |||
| bb9e79daa7 | |||
| 6d9d4157ef | |||
| d37eaa5941 | |||
| d4192b9d35 | |||
| 1fe2ea5a87 | |||
| f4f1abb27a | |||
| f98719902b | |||
| 7288ae1c16 | |||
| 0f2cc53be7 | |||
| 387eddcf75 | |||
| 71e70aed14 | |||
| 2080878d82 | |||
| a8b295c516 | |||
| cf2e0c7959 | |||
| 589060d10f | |||
| 60fa704f78 | |||
| d014d88937 | |||
| f5c287a6e6 | |||
| 568b44eb9d | |||
| 21d25b23d9 | |||
| 9c7b4ff9ba | |||
| 874574513c | |||
| d198c4426f | |||
| 6884a3ac56 | |||
| 2b47e779ac | |||
| ff11467a0c | |||
| 241afeb1b7 | |||
| 5d96a2dc9e | |||
| 7324140d20 | |||
| f43c39c905 | |||
| 6f0461c569 | |||
| 04df9b8f49 | |||
| 0d4040aa63 | |||
| 74a014743a | |||
| 7adeb461e0 | |||
| 0f7ad1b5bf | |||
| 148dc95eb1 | |||
| 7205edac85 | |||
| 8047a0bb78 | |||
| ccb719eae3 | |||
| 3426e6274c | |||
| 128acaff8a | |||
| 6e8bb6c4a9 | |||
| f500ab0f9b | |||
| cb02b0e776 | |||
| dd7369df48 | |||
| 4116e6dd18 | |||
| 443e9ee618 | |||
| 50b20c2bb7 | |||
| d939016a09 | |||
| a83529c844 | |||
| 32e851617e | |||
| 1891f8af70 | |||
| 93e5214d01 | |||
| 7758ba3c7e | |||
| a7f71f4d9b | |||
| 36553264ce | |||
| 13183c89ce | |||
| 4d3dd9b9f6 | |||
| c558391e2c | |||
| 596936f18c | |||
| 6a2939a4d4 | |||
| 45491f0756 | |||
| 2c757399b2 |
+52
-46
@@ -1,13 +1,15 @@
|
||||
plugins {
|
||||
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.4.0-rc' apply false
|
||||
id 'org.jetbrains.dokka' version '0.10.1' apply false
|
||||
id 'org.asciidoctor.jvm.convert' version '2.4.0'
|
||||
id 'io.spring.nohttp' version '0.0.5.RELEASE'
|
||||
id 'de.undercouch.download' version '4.0.4'
|
||||
id "io.freefair.aspectj" version '5.0.0' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.4.21' apply false
|
||||
id 'org.jetbrains.dokka' version '0.10.1' apply false
|
||||
id 'org.asciidoctor.jvm.convert' version '3.1.0'
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.1.0'
|
||||
id 'de.undercouch.download' version '4.1.1'
|
||||
id "io.freefair.aspectj" version '5.1.1' apply false
|
||||
id "com.github.ben-manes.versions" version '0.28.0'
|
||||
id "me.champeau.gradle.jmh" version "0.5.0" apply false
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.21" apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -23,22 +25,22 @@ configure(allprojects) { project ->
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.11.2"
|
||||
mavenBom "io.netty:netty-bom:4.1.51.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.0-M2"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR5"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.0-M1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.31.v20200723"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.0-rc"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.8-1.4.0-rc"
|
||||
mavenBom "org.junit:junit-bom:5.6.2"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.0"
|
||||
mavenBom "io.netty:netty-bom:4.1.54.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.2"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR8"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.0"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.35.v20201120"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.21"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.2"
|
||||
mavenBom "org.junit:junit-bom:5.7.0"
|
||||
}
|
||||
dependencies {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.13.3') {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.0') {
|
||||
entry 'log4j-api'
|
||||
entry 'log4j-core'
|
||||
entry 'log4j-slf4j-impl'
|
||||
entry 'log4j-jul'
|
||||
entry 'log4j-slf4j-impl'
|
||||
}
|
||||
dependency "org.slf4j:slf4j-api:1.7.30"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
@@ -51,7 +53,7 @@ configure(allprojects) { project ->
|
||||
entry 'aspectjtools'
|
||||
entry 'aspectjweaver'
|
||||
}
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.5') {
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.7') {
|
||||
entry 'groovy'
|
||||
entry 'groovy-jsr223'
|
||||
entry 'groovy-templates' // requires findbugs for warning-free compilation
|
||||
@@ -62,18 +64,18 @@ configure(allprojects) { project ->
|
||||
dependency "io.reactivex:rxjava:1.3.8"
|
||||
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
|
||||
dependency "io.reactivex.rxjava2:rxjava:2.2.19"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.0.5"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.2.RELEASE"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.0.8"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
dependency "com.fasterxml:aalto-xml:1.2.2"
|
||||
dependency("com.fasterxml.woodstox:woodstox-core:6.1.1") {
|
||||
dependency("com.fasterxml.woodstox:woodstox-core:6.2.3") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
dependency "com.google.code.gson:gson:2.8.6"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.12.4"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.14.0"
|
||||
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.12") {
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.14") {
|
||||
exclude group: "xpp3", name: "xpp3_min"
|
||||
exclude group: "xmlpull", name: "xmlpull"
|
||||
}
|
||||
@@ -86,11 +88,15 @@ configure(allprojects) { project ->
|
||||
entry 'jibx-run'
|
||||
}
|
||||
dependency "org.ogce:xpp3:1.1.6"
|
||||
dependency "org.yaml:snakeyaml:1.26"
|
||||
dependency "org.yaml:snakeyaml:1.27"
|
||||
dependencySet(group: 'org.jetbrains.kotlinx', version: '1.0.0') {
|
||||
entry 'kotlinx-serialization-core'
|
||||
entry 'kotlinx-serialization-json'
|
||||
}
|
||||
|
||||
dependency "com.h2database:h2:1.4.200"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.8.5"
|
||||
dependency "com.github.librepdf:openpdf:1.3.20"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.8.6"
|
||||
dependency "com.github.librepdf:openpdf:1.3.23"
|
||||
dependency "com.rometools:rome:1.15.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.3"
|
||||
@@ -103,7 +109,7 @@ configure(allprojects) { project ->
|
||||
entry 'activemq-stomp'
|
||||
}
|
||||
dependency "org.apache.bcel:bcel:6.0"
|
||||
dependency "org.apache.commons:commons-pool2:2.8.0"
|
||||
dependency "org.apache.commons:commons-pool2:2.9.0"
|
||||
dependencySet(group: 'org.apache.derby', version: '10.14.2.0') {
|
||||
entry 'derby'
|
||||
entry 'derbyclient'
|
||||
@@ -117,23 +123,23 @@ configure(allprojects) { project ->
|
||||
dependency "net.sf.ehcache:ehcache:2.10.6"
|
||||
dependency "org.ehcache:jcache:1.0.1"
|
||||
dependency "org.ehcache:ehcache:3.4.0"
|
||||
dependency "org.hibernate:hibernate-core:5.4.19.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.1.5.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.45"
|
||||
dependency "org.hibernate:hibernate-core:5.4.25.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.1.6.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.46"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.37') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.40') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.37') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.40') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.1.3.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.3.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-websockets-jsr') {
|
||||
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
|
||||
@@ -148,17 +154,17 @@ configure(allprojects) { project ->
|
||||
entry 'okhttp'
|
||||
entry 'mockwebserver'
|
||||
}
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.12") {
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.1'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.1'
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.3'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.3'
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.4"
|
||||
|
||||
dependency "org.jruby:jruby:9.2.12.0"
|
||||
dependency "org.jruby:jruby:9.2.13.0"
|
||||
dependency "org.python:jython-standalone:2.7.1"
|
||||
dependency "org.mozilla:rhino:1.7.11"
|
||||
|
||||
@@ -175,7 +181,7 @@ configure(allprojects) { project ->
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
|
||||
dependency("junit:junit:4.13") {
|
||||
dependency("junit:junit:4.13.1") {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
|
||||
@@ -184,25 +190,25 @@ configure(allprojects) { project ->
|
||||
dependency "org.testng:testng:7.3.0"
|
||||
dependency "org.hamcrest:hamcrest:2.1"
|
||||
dependency "org.awaitility:awaitility:3.1.6"
|
||||
dependency "org.assertj:assertj-core:3.16.1"
|
||||
dependency "org.assertj:assertj-core:3.18.1"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.6.2') {
|
||||
entry 'xmlunit-assertj'
|
||||
entry('xmlunit-matchers') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '3.4.6') {
|
||||
dependencySet(group: 'org.mockito', version: '3.6.28') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
entry 'mockito-junit-jupiter'
|
||||
}
|
||||
dependency "io.mockk:mockk:1.10.0"
|
||||
dependency "io.mockk:mockk:1.10.2"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.43.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.45.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.43.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.45.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -285,7 +291,6 @@ configure(allprojects) { project ->
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spring.io/libs-spring-framework-build" }
|
||||
maven { url "https://repo.spring.io/milestone" } // Reactor
|
||||
}
|
||||
}
|
||||
configurations.all {
|
||||
@@ -334,7 +339,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.35"
|
||||
toolVersion = "8.38"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
@@ -374,8 +379,9 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
|
||||
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
|
||||
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
|
||||
"https://junit.org/junit4/javadoc/4.13/",
|
||||
"https://junit.org/junit5/docs/5.6.2/api/"
|
||||
"https://projectreactor.io/docs/test/release/api/",
|
||||
"https://junit.org/junit4/javadoc/4.13.1/",
|
||||
"https://junit.org/junit5/docs/5.7.0/api/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
changelog:
|
||||
repository: spring-projects/spring-framework
|
||||
sections:
|
||||
- title: ":star: New Features"
|
||||
labels:
|
||||
- "type: enhancement"
|
||||
- title: ":beetle: Bug Fixes"
|
||||
labels:
|
||||
- "type: bug"
|
||||
- "type: regression"
|
||||
- title: ":notebook_with_decorative_cover: Documentation"
|
||||
labels:
|
||||
- "type: documentation"
|
||||
- title: ":hammer: Dependency Upgrades"
|
||||
sort: "title"
|
||||
labels:
|
||||
- "type: dependency-upgrade"
|
||||
@@ -0,0 +1,9 @@
|
||||
logging:
|
||||
level:
|
||||
io.spring.concourse: DEBUG
|
||||
distribute:
|
||||
optional-deployments:
|
||||
- '.*\\.zip'
|
||||
spring:
|
||||
main:
|
||||
banner-mode: off
|
||||
@@ -12,7 +12,7 @@ case "$1" in
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_linux_hotspot_14.0.2_12.tar.gz"
|
||||
;;
|
||||
java15)
|
||||
echo "https://download.java.net/java/early_access/jdk15/33/GPL/openjdk-15-ea+33_linux-x64_bin.tar.gz"
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15%2B36/OpenJDK15U-jdk_x64_linux_hotspot_15_36.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.3/concourse-java.sh > /opt/concourse-java.sh
|
||||
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.2.0/concourse-release-scripts-0.2.0.jar
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.2.1/concourse-release-scripts-0.2.1.jar
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
|
||||
+197
-77
@@ -1,28 +1,61 @@
|
||||
anchors:
|
||||
artifactory-task-params: &artifactory-task-params
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
ARTIFACTORY_PASSWORD: ((artifactory-password))
|
||||
bintray-task-params: &bintray-task-params
|
||||
BINTRAY_SUBJECT: ((bintray-subject))
|
||||
BINTRAY_REPO: ((bintray-repo))
|
||||
BINTRAY_USERNAME: ((bintray-username))
|
||||
BINTRAY_API_KEY: ((bintray-api-key))
|
||||
docker-resource-source: &docker-resource-source
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
gradle-enterprise-task-params: &gradle-enterprise-task-params
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
slack-fail-params: &slack-fail-params
|
||||
text: >
|
||||
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
|
||||
[$TEXT_FILE_CONTENT]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
sonatype-task-params: &sonatype-task-params
|
||||
SONATYPE_USER_TOKEN: ((sonatype-user-token))
|
||||
SONATYPE_PASSWORD_TOKEN: ((sonatype-user-token-password))
|
||||
changelog-task-params: &changelog-task-params
|
||||
name: generated-changelog/tag
|
||||
tag: generated-changelog/tag
|
||||
body: generated-changelog/changelog.md
|
||||
github-task-params: &github-task-params
|
||||
GITHUB_USERNAME: ((github-username))
|
||||
GITHUB_TOKEN: ((github-ci-release-token))
|
||||
|
||||
resource_types:
|
||||
- name: artifactory-resource
|
||||
type: docker-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/artifactory-resource
|
||||
tag: 0.0.12-SNAPSHOT
|
||||
tag: 0.0.12
|
||||
- name: github-status-resource
|
||||
type: docker-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: dpb587/github-status-resource
|
||||
tag: master
|
||||
- name: email
|
||||
type: docker-image
|
||||
source:
|
||||
repository: pcfseceng/email-resource
|
||||
tag: 1.0.19
|
||||
- name: slack-notification
|
||||
type: docker-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: cfcommunity/slack-notification-resource
|
||||
tag: latest
|
||||
|
||||
resources:
|
||||
- name: git-repo
|
||||
type: git
|
||||
icon: github-circle
|
||||
icon: github
|
||||
source:
|
||||
uri: ((github-repo))
|
||||
username: ((github-username))
|
||||
@@ -37,7 +70,7 @@ resources:
|
||||
location: Europe/Vienna
|
||||
- name: ci-images-git-repo
|
||||
type: git
|
||||
icon: github-circle
|
||||
icon: github
|
||||
source:
|
||||
uri: ((github-repo))
|
||||
branch: ((branch))
|
||||
@@ -46,34 +79,26 @@ resources:
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
repository: ((docker-hub-organization))/spring-framework-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk11-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk11-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk14-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk14-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk15-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk15-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: artifactory-repo
|
||||
type: artifactory-resource
|
||||
icon: package-variant
|
||||
@@ -119,6 +144,24 @@ resources:
|
||||
icon: slack
|
||||
source:
|
||||
url: ((slack-webhook-url))
|
||||
- name: github-pre-release
|
||||
type: github-release
|
||||
icon: briefcase-download-outline
|
||||
source:
|
||||
owner: spring-projects
|
||||
repository: spring-framework
|
||||
access_token: ((github-ci-release-token))
|
||||
pre_release: true
|
||||
release: false
|
||||
- name: github-release
|
||||
type: github-release
|
||||
icon: briefcase-download
|
||||
source:
|
||||
owner: spring-projects
|
||||
repository: spring-framework
|
||||
access_token: ((github-ci-release-token))
|
||||
pre_release: false
|
||||
|
||||
jobs:
|
||||
- name: build-spring-framework-ci-images
|
||||
plan:
|
||||
@@ -158,23 +201,14 @@ jobs:
|
||||
file: git-repo/ci/tasks/build-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
<<: *gradle-enterprise-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- put: artifactory-repo
|
||||
@@ -224,23 +258,14 @@ jobs:
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
<<: *gradle-enterprise-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk14-build
|
||||
@@ -261,23 +286,14 @@ jobs:
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
<<: *gradle-enterprise-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk14-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk14-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk15-build
|
||||
@@ -298,23 +314,14 @@ jobs:
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
<<: *gradle-enterprise-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: stage-milestone
|
||||
@@ -328,9 +335,7 @@ jobs:
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
@@ -355,13 +360,128 @@ jobs:
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
ARTIFACTORY_PASSWORD: ((artifactory-password))
|
||||
<<: *artifactory-task-params
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
<<: *github-task-params
|
||||
- put: github-pre-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
- name: stage-rc
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-rc
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-rc]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *artifactory-task-params
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *github-task-params
|
||||
- put: github-pre-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
- name: stage-release
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-release
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-release]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *artifactory-task-params
|
||||
<<: *bintray-task-params
|
||||
- name: sync-to-maven-central
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
- get: artifactory-repo
|
||||
trigger: true
|
||||
passed: [promote-release]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: sync-to-maven-central
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/sync-to-maven-central.yml
|
||||
params:
|
||||
<<: *bintray-task-params
|
||||
<<: *sonatype-task-params
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *github-task-params
|
||||
- put: github-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
|
||||
groups:
|
||||
- name: "Build"
|
||||
- name: "builds"
|
||||
jobs: ["build", "jdk11-build", "jdk14-build", "jdk15-build"]
|
||||
- name: "Release"
|
||||
jobs: ["stage-milestone", "promote-milestone"]
|
||||
- name: "CI Images"
|
||||
- name: "releases"
|
||||
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone","promote-rc", "promote-release", "sync-to-maven-central"]
|
||||
- name: "ci-images"
|
||||
jobs: ["build-spring-framework-ci-images"]
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
CONFIG_DIR=git-repo/ci/config
|
||||
version=$( cat version/version )
|
||||
|
||||
java -jar /github-changelog-generator.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/changelog-generator.yml \
|
||||
${version} generated-changelog/changelog.md
|
||||
|
||||
echo ${version} > generated-changelog/version
|
||||
echo v${version} > generated-changelog/tag
|
||||
@@ -1,13 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
CONFIG_DIR=git-repo/ci/config
|
||||
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
|
||||
java -jar /opt/concourse-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
|
||||
java -jar /opt/concourse-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
java -jar /opt/concourse-release-scripts.jar distribute $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
|
||||
java -jar /opt/concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
distribute $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
echo "Promotion complete"
|
||||
echo $version > version/version
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
echo "Sync complete"
|
||||
echo $version > version/version
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: docker-image
|
||||
source:
|
||||
repository: springio/github-changelog-generator
|
||||
tag: '0.0.4'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: version
|
||||
outputs:
|
||||
- name: generated-changelog
|
||||
params:
|
||||
GITHUB_ORGANIZATION:
|
||||
GITHUB_REPO:
|
||||
GITHUB_USERNAME:
|
||||
GITHUB_TOKEN:
|
||||
RELEASE_TYPE:
|
||||
run:
|
||||
path: git-repo/ci/scripts/generate-changelog.sh
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
outputs:
|
||||
- name: version
|
||||
params:
|
||||
BINTRAY_REPO:
|
||||
BINTRAY_SUBJECT:
|
||||
BINTRAY_USERNAME:
|
||||
BINTRAY_API_KEY:
|
||||
SONATYPE_USER_TOKEN:
|
||||
SONATYPE_PASSWORD_TOKEN:
|
||||
run:
|
||||
path: git-repo/ci/scripts/sync-to-maven-central.sh
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=5.3.0-SNAPSHOT
|
||||
version=5.3.2
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
+45
-35
@@ -3,7 +3,7 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.2.RELEASE")
|
||||
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.5.0")
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -106,11 +106,14 @@ dokka {
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task downloadResources(type: Download) {
|
||||
def version = "0.2.2.RELEASE"
|
||||
def version = "0.2.5"
|
||||
src "https://repo.spring.io/release/io/spring/docresources/" +
|
||||
"spring-doc-resources/$version/spring-doc-resources-${version}.zip"
|
||||
dest project.file("$buildDir/docs/spring-doc-resources.zip")
|
||||
@@ -124,35 +127,8 @@ task extractDocResources(type: Copy, dependsOn: downloadResources) {
|
||||
}
|
||||
|
||||
asciidoctorj {
|
||||
modules {
|
||||
pdf {
|
||||
version '1.5.0-beta.8'
|
||||
}
|
||||
}
|
||||
version = '2.4.1'
|
||||
fatalWarnings ".*"
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce the Spring Framework Reference documentation
|
||||
* from "src/docs/asciidoc" into "build/asciidoc/html5"
|
||||
*/
|
||||
asciidoctor {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations 'asciidoctorExt'
|
||||
sources {
|
||||
include '*.adoc'
|
||||
}
|
||||
outputDir "$buildDir/docs/ref-docs/"
|
||||
resources {
|
||||
from(sourceDir) {
|
||||
include 'images/*.png', 'css/**', 'js/**'
|
||||
}
|
||||
from extractDocResources
|
||||
}
|
||||
logDocuments = true
|
||||
outputOptions {
|
||||
backends = ["html5", "pdf"]
|
||||
}
|
||||
options doctype: 'book', eruby: 'erubis'
|
||||
attributes([
|
||||
icons: 'font',
|
||||
@@ -171,10 +147,44 @@ asciidoctor {
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the Spring Framework Reference documentation from "src/docs/asciidoc"
|
||||
* in "build/docs/ref-docs/html5".
|
||||
*/
|
||||
asciidoctor {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations 'asciidoctorExt'
|
||||
sources {
|
||||
include '*.adoc'
|
||||
}
|
||||
outputDir "$buildDir/docs/ref-docs/html5"
|
||||
logDocuments = true
|
||||
resources {
|
||||
from(sourceDir) {
|
||||
include 'images/*.png', 'css/**', 'js/**'
|
||||
}
|
||||
from extractDocResources
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the Spring Framework Reference documentation from "src/docs/asciidoc"
|
||||
* in "build/docs/ref-docs/pdf".
|
||||
*/
|
||||
asciidoctorPdf {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations 'asciidoctorExt'
|
||||
sources {
|
||||
include '*.adoc'
|
||||
}
|
||||
outputDir "$buildDir/docs/ref-docs/pdf"
|
||||
logDocuments = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip all docs (API and reference) into a single archive
|
||||
*/
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'dokka']) {
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokka']) {
|
||||
group = "Distribution"
|
||||
description = "Builds -${archiveClassifier} archive containing api and reference " +
|
||||
"for deployment at https://docs.spring.io/spring-framework/docs."
|
||||
@@ -187,11 +197,11 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'dokka']) {
|
||||
from (api) {
|
||||
into "javadoc-api"
|
||||
}
|
||||
from ("$asciidoctor.outputDir/html5") {
|
||||
into "spring-framework-reference"
|
||||
from ("$asciidoctor.outputDir") {
|
||||
into "reference/html"
|
||||
}
|
||||
from ("$asciidoctor.outputDir/pdf") {
|
||||
into "spring-framework-reference/pdf"
|
||||
from ("$asciidoctorPdf.outputDir") {
|
||||
into "reference/pdf"
|
||||
}
|
||||
from (dokka) {
|
||||
into "kdoc-api"
|
||||
|
||||
+18
-2
@@ -29,12 +29,11 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
|
||||
}
|
||||
|
||||
|
||||
// Use separate main/test outputs (prevents WTP from packaging test classes)
|
||||
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
|
||||
eclipse.classpath.file.beforeMerged { classpath ->
|
||||
classpath.entries.findAll{ it instanceof SourceFolder }.each {
|
||||
if(it.output.startsWith("bin/")) {
|
||||
if (it.output.startsWith("bin/")) {
|
||||
it.output = null
|
||||
}
|
||||
}
|
||||
@@ -56,6 +55,23 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that test fixture dependencies are handled properly in Gradle 6.7.
|
||||
// Bug fixed in Gradle 6.8: https://github.com/gradle/gradle/issues/14932
|
||||
eclipse.classpath.file.whenMerged {
|
||||
entries.findAll { it instanceof ProjectDependency }.each {
|
||||
it.entryAttributes.remove('without_test_code')
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that JMH sources and resources are treated as test classpath entries
|
||||
// so that they can see test fixtures.
|
||||
// https://github.com/melix/jmh-gradle-plugin/issues/157
|
||||
eclipse.classpath.file.whenMerged {
|
||||
entries.findAll { it.path =~ /src\/jmh\/(java|resources)/ }.each {
|
||||
it.entryAttributes['test'] = 'true'
|
||||
}
|
||||
}
|
||||
|
||||
// Allow projects to be used as WTP modules
|
||||
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -130,7 +130,7 @@ fi
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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
|
||||
|
||||
Vendored
+3
-18
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -54,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -64,21 +64,6 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.transaction.testfixture.CallCountingTransactionManage
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
||||
|
||||
/**
|
||||
* Integration tests cornering bug SPR-8651, which revealed that @Scheduled methods may
|
||||
@@ -52,7 +52,7 @@ import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
* @since 3.1
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
|
||||
@Test
|
||||
@@ -182,7 +182,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
@Aspect
|
||||
public static class MyAspect {
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger(0);
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
@org.aspectj.lang.annotation.Before("execution(* scheduled())")
|
||||
public void checkTransaction() {
|
||||
@@ -200,7 +200,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
@Repository
|
||||
static class MyRepositoryImpl implements MyRepository {
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger(0);
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
@Transactional
|
||||
@Scheduled(fixedDelay = 5)
|
||||
@@ -226,7 +226,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
@Repository
|
||||
static class MyRepositoryWithScheduledMethodImpl implements MyRepositoryWithScheduledMethod {
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger(0);
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
@Autowired(required = false)
|
||||
private MyAspect myAspect;
|
||||
|
||||
+3
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -350,17 +350,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
return this.discoveredThrowingType;
|
||||
}
|
||||
|
||||
private boolean isVariableName(String name) {
|
||||
char[] chars = name.toCharArray();
|
||||
if (!Character.isJavaIdentifierStart(chars[0])) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
if (!Character.isJavaIdentifierPart(chars[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
private static boolean isVariableName(String name) {
|
||||
return AspectJProxyUtils.isVariableName(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -640,7 +631,6 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
|
||||
// TODO AopUtils.invokeJoinpointUsingReflection
|
||||
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
|
||||
+2
-14
@@ -470,22 +470,10 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
*/
|
||||
@Nullable
|
||||
private String maybeExtractVariableName(@Nullable String candidateToken) {
|
||||
if (!StringUtils.hasLength(candidateToken)) {
|
||||
return null;
|
||||
}
|
||||
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
|
||||
Character.isLowerCase(candidateToken.charAt(0))) {
|
||||
char[] tokenChars = candidateToken.toCharArray();
|
||||
for (char tokenChar : tokenChars) {
|
||||
if (!Character.isJavaIdentifierPart(tokenChar)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (AspectJProxyUtils.isVariableName(candidateToken)) {
|
||||
return candidateToken;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -21,6 +21,8 @@ import java.util.List;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for working with AspectJ proxies.
|
||||
@@ -73,4 +75,19 @@ public abstract class AspectJProxyUtils {
|
||||
((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
|
||||
}
|
||||
|
||||
static boolean isVariableName(@Nullable String name) {
|
||||
if (!StringUtils.hasLength(name)) {
|
||||
return false;
|
||||
}
|
||||
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < name.length(); i++) {
|
||||
if (!Character.isJavaIdentifierPart(name.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-3
@@ -221,10 +221,12 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getParameterNames() {
|
||||
if (this.parameterNames == null) {
|
||||
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
String[] parameterNames = this.parameterNames;
|
||||
if (parameterNames == null) {
|
||||
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
this.parameterNames = parameterNames;
|
||||
}
|
||||
return this.parameterNames;
|
||||
return parameterNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -160,23 +160,12 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton aspect instance for the supplied aspect type. An instance
|
||||
* is created if one cannot be found in the instance cache.
|
||||
* Get the singleton aspect instance for the supplied aspect type.
|
||||
* An instance is created if one cannot be found in the instance cache.
|
||||
*/
|
||||
private Object getSingletonAspectInstance(Class<?> aspectClass) {
|
||||
// Quick check without a lock...
|
||||
Object instance = aspectCache.get(aspectClass);
|
||||
if (instance == null) {
|
||||
synchronized (aspectCache) {
|
||||
// To be safe, check within full lock now...
|
||||
instance = aspectCache.get(aspectClass);
|
||||
if (instance == null) {
|
||||
instance = new SimpleAspectInstanceFactory(aspectClass).getAspectInstance();
|
||||
aspectCache.put(aspectClass, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
return aspectCache.computeIfAbsent(aspectClass,
|
||||
clazz -> new SimpleAspectInstanceFactory(clazz).getAspectInstance());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-10
@@ -51,6 +51,7 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConvertingComparator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.comparator.InstanceComparator;
|
||||
|
||||
@@ -70,7 +71,11 @@ import org.springframework.util.comparator.InstanceComparator;
|
||||
@SuppressWarnings("serial")
|
||||
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
|
||||
|
||||
private static final Comparator<Method> METHOD_COMPARATOR;
|
||||
// Exclude @Pointcut methods
|
||||
private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
|
||||
.and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
|
||||
|
||||
private static final Comparator<Method> adviceMethodComparator;
|
||||
|
||||
static {
|
||||
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
|
||||
@@ -86,7 +91,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return (ann != null ? ann.getAnnotation() : null);
|
||||
});
|
||||
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
|
||||
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
|
||||
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,15 +165,10 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}
|
||||
|
||||
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
|
||||
final List<Method> methods = new ArrayList<>();
|
||||
ReflectionUtils.doWithMethods(aspectClass, method -> {
|
||||
// Exclude pointcuts
|
||||
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
|
||||
methods.add(method);
|
||||
}
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
List<Method> methods = new ArrayList<>();
|
||||
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
|
||||
if (methods.size() > 1) {
|
||||
methods.sort(METHOD_COMPARATOR);
|
||||
methods.sort(adviceMethodComparator);
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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,13 +30,14 @@ public class AdviceEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link AdviceEntry} class.
|
||||
* @param kind the kind of advice represented by this entry (before, after, around, etc.)
|
||||
* Create a new {@code AdviceEntry} instance.
|
||||
* @param kind the kind of advice represented by this entry (before, after, around)
|
||||
*/
|
||||
public AdviceEntry(String kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Advice (" + this.kind + ")";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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,13 +30,14 @@ public class AdvisorEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link AdvisorEntry} class.
|
||||
* Create a new {@code AdvisorEntry} instance.
|
||||
* @param name the bean name of the advisor
|
||||
*/
|
||||
public AdvisorEntry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Advisor '" + this.name + "'";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -34,7 +34,7 @@ public class AspectEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AspectEntry.
|
||||
* Create a new {@code AspectEntry} instance.
|
||||
* @param id the id of the aspect element
|
||||
* @param ref the bean name referenced by this aspect element
|
||||
*/
|
||||
@@ -43,6 +43,7 @@ public class AspectEntry implements ParseState.Entry {
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" : "ref='" + this.ref + "'");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -28,14 +28,16 @@ public class PointcutEntry implements ParseState.Entry {
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link PointcutEntry} class.
|
||||
* Create a new {@code PointcutEntry} instance.
|
||||
* @param name the bean name of the pointcut
|
||||
*/
|
||||
public PointcutEntry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pointcut '" + this.name + "'";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -114,6 +114,15 @@ public interface Advised extends TargetClassAware {
|
||||
*/
|
||||
Advisor[] getAdvisors();
|
||||
|
||||
/**
|
||||
* Return the number of advisors applying to this proxy.
|
||||
* <p>The default implementation delegates to {@code getAdvisors().length}.
|
||||
* @since 5.3.1
|
||||
*/
|
||||
default int getAdvisorCount() {
|
||||
return getAdvisors().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an advisor at the end of the advisor chain.
|
||||
* <p>The Advisor may be an {@link org.springframework.aop.IntroductionAdvisor},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -95,12 +95,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
*/
|
||||
private List<Advisor> advisors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Array updated on changes to the advisors list, which is easier
|
||||
* to manipulate internally.
|
||||
*/
|
||||
private Advisor[] advisorArray = new Advisor[0];
|
||||
|
||||
|
||||
/**
|
||||
* No-arg constructor for use as a JavaBean.
|
||||
@@ -244,7 +238,12 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
|
||||
@Override
|
||||
public final Advisor[] getAdvisors() {
|
||||
return this.advisorArray;
|
||||
return this.advisors.toArray(new Advisor[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdvisorCount() {
|
||||
return this.advisors.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -292,7 +291,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
}
|
||||
|
||||
updateAdvisorArray();
|
||||
adviceChanged();
|
||||
}
|
||||
|
||||
@@ -339,7 +337,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
Assert.notNull(advisor, "Advisor must not be null");
|
||||
this.advisors.add(advisor);
|
||||
}
|
||||
updateAdvisorArray();
|
||||
adviceChanged();
|
||||
}
|
||||
}
|
||||
@@ -363,27 +360,18 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
"Illegal position " + pos + " in advisor list with size " + this.advisors.size());
|
||||
}
|
||||
this.advisors.add(pos, advisor);
|
||||
updateAdvisorArray();
|
||||
adviceChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bring the array up to date with the list.
|
||||
*/
|
||||
protected final void updateAdvisorArray() {
|
||||
this.advisorArray = this.advisors.toArray(new Advisor[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows uncontrolled access to the {@link List} of {@link Advisor Advisors}.
|
||||
* <p>Use with care, and remember to {@link #updateAdvisorArray() refresh the advisor array}
|
||||
* and {@link #adviceChanged() fire advice changed events} when making any modifications.
|
||||
* <p>Use with care, and remember to {@link #adviceChanged() fire advice changed events}
|
||||
* when making any modifications.
|
||||
*/
|
||||
protected final List<Advisor> getAdvisorsInternal() {
|
||||
return this.advisors;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addAdvice(Advice advice) throws AopConfigException {
|
||||
int pos = this.advisors.size();
|
||||
@@ -521,7 +509,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
Assert.notNull(advisor, "Advisor must not be null");
|
||||
this.advisors.add(advisor);
|
||||
}
|
||||
updateAdvisorArray();
|
||||
adviceChanged();
|
||||
}
|
||||
|
||||
@@ -536,7 +523,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
copy.advisorChainFactory = this.advisorChainFactory;
|
||||
copy.interfaces = this.interfaces;
|
||||
copy.advisors = this.advisors;
|
||||
copy.updateAdvisorArray();
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -553,7 +539,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
this.methodCache = new ConcurrentHashMap<>(32);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toProxyConfigString() {
|
||||
return toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -206,7 +206,7 @@ public abstract class AopProxyUtils {
|
||||
* Check equality of the advisors behind the given AdvisedSupport objects.
|
||||
*/
|
||||
public static boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b) {
|
||||
return Arrays.equals(a.getAdvisors(), b.getAdvisors());
|
||||
return a.getAdvisorCount() == b.getAdvisorCount() && Arrays.equals(a.getAdvisors(), b.getAdvisors());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -53,6 +52,7 @@ import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -125,7 +125,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
|
||||
Assert.notNull(config, "AdvisedSupport must not be null");
|
||||
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
|
||||
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
|
||||
throw new AopConfigException("No advisors and no TargetSource specified");
|
||||
}
|
||||
this.advised = config;
|
||||
@@ -325,7 +325,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
if (isStatic && isFrozen) {
|
||||
Method[] methods = rootClass.getMethods();
|
||||
Callback[] fixedCallbacks = new Callback[methods.length];
|
||||
this.fixedInterceptorMap = new HashMap<>(methods.length);
|
||||
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
|
||||
|
||||
// TODO: small memory optimization here (can skip creation for methods with no advice)
|
||||
for (int x = 0; x < methods.length; x++) {
|
||||
@@ -942,11 +942,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
// Advice instance identity is unimportant to the proxy class:
|
||||
// All that matters is type and ordering.
|
||||
Advisor[] thisAdvisors = this.advised.getAdvisors();
|
||||
Advisor[] thatAdvisors = otherAdvised.getAdvisors();
|
||||
if (thisAdvisors.length != thatAdvisors.length) {
|
||||
if (this.advised.getAdvisorCount() != otherAdvised.getAdvisorCount()) {
|
||||
return false;
|
||||
}
|
||||
Advisor[] thisAdvisors = this.advised.getAdvisors();
|
||||
Advisor[] thatAdvisors = otherAdvised.getAdvisors();
|
||||
for (int i = 0; i < thisAdvisors.length; i++) {
|
||||
Advisor thisAdvisor = thisAdvisors[i];
|
||||
Advisor thatAdvisor = thatAdvisors[i];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -57,6 +57,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Dave Syer
|
||||
* @author Sergey Tsypanov
|
||||
* @see java.lang.reflect.Proxy
|
||||
* @see AdvisedSupport
|
||||
* @see ProxyFactory
|
||||
@@ -82,6 +83,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
/** Config used to configure this proxy. */
|
||||
private final AdvisedSupport advised;
|
||||
|
||||
private final Class<?>[] proxiedInterfaces;
|
||||
|
||||
/**
|
||||
* Is the {@link #equals} method defined on the proxied interfaces?
|
||||
*/
|
||||
@@ -101,10 +104,12 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
*/
|
||||
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
|
||||
Assert.notNull(config, "AdvisedSupport must not be null");
|
||||
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
|
||||
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
|
||||
throw new AopConfigException("No advisors and no TargetSource specified");
|
||||
}
|
||||
this.advised = config;
|
||||
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
|
||||
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,9 +123,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
|
||||
}
|
||||
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
|
||||
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
|
||||
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
|
||||
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +16,7 @@
|
||||
|
||||
package org.springframework.aop.framework;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
@@ -34,7 +34,7 @@ public class ProxyCreatorSupport extends AdvisedSupport {
|
||||
|
||||
private AopProxyFactory aopProxyFactory;
|
||||
|
||||
private final List<AdvisedSupportListener> listeners = new LinkedList<>();
|
||||
private final List<AdvisedSupportListener> listeners = new ArrayList<>();
|
||||
|
||||
/** Set to true when the first AOP proxy has been created. */
|
||||
private boolean active = false;
|
||||
|
||||
+6
@@ -39,6 +39,7 @@ import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
|
||||
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
|
||||
import org.springframework.aop.target.SingletonTargetSource;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
@@ -270,6 +271,11 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
|
||||
return pvs; // skip postProcessPropertyValues
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a proxy with the configured interceptors if the bean is
|
||||
* identified as one to proxy by the subclass.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -45,7 +45,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
@Nullable
|
||||
private final String methodName;
|
||||
|
||||
private final AtomicInteger evaluations = new AtomicInteger(0);
|
||||
private final AtomicInteger evaluations = new AtomicInteger();
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+3
-4
@@ -23,7 +23,6 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
@@ -136,7 +135,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
|
||||
List<Advisor> advisors = new LinkedList<>();
|
||||
List<Advisor> advisors = new ArrayList<>();
|
||||
PerTargetAspect aspect1 = new PerTargetAspect();
|
||||
aspect1.count = 100;
|
||||
aspect1.setOrder(10);
|
||||
@@ -164,7 +163,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
|
||||
List<Advisor> advisors = new LinkedList<>();
|
||||
List<Advisor> advisors = new ArrayList<>();
|
||||
PerTargetAspectWithOrderAnnotation10 aspect1 = new PerTargetAspectWithOrderAnnotation10();
|
||||
aspect1.count = 100;
|
||||
advisors.addAll(
|
||||
@@ -392,7 +391,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
@Test
|
||||
void introductionOnTargetExcludedByTypePattern() {
|
||||
LinkedList<Object> target = new LinkedList<>();
|
||||
ArrayList<Object> target = new ArrayList<>();
|
||||
List<?> proxy = (List<?>) createProxy(target,
|
||||
AopUtils.findAdvisorsThatCanApply(
|
||||
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
|
||||
+2
-2
@@ -143,13 +143,13 @@ public class CustomizableTraceInterceptorTests {
|
||||
given(log.isTraceEnabled()).willReturn(true);
|
||||
|
||||
CustomizableTraceInterceptor interceptor = new StubCustomizableTraceInterceptor(log);
|
||||
interceptor.setEnterMessage(new StringBuffer()
|
||||
interceptor.setEnterMessage(new StringBuilder()
|
||||
.append("Entering the '").append(CustomizableTraceInterceptor.PLACEHOLDER_METHOD_NAME)
|
||||
.append("' method of the [").append(CustomizableTraceInterceptor.PLACEHOLDER_TARGET_CLASS_NAME)
|
||||
.append("] class with the following args (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENTS)
|
||||
.append(") and arg types (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENT_TYPES)
|
||||
.append(").").toString());
|
||||
interceptor.setExitMessage(new StringBuffer()
|
||||
interceptor.setExitMessage(new StringBuilder()
|
||||
.append("Exiting the '").append(CustomizableTraceInterceptor.PLACEHOLDER_METHOD_NAME)
|
||||
.append("' method of the [").append(CustomizableTraceInterceptor.PLACEHOLDER_TARGET_CLASS_SHORT_NAME)
|
||||
.append("] class with the following args (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENTS)
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.testfixture.EnabledForTestGroups;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
@@ -77,7 +77,7 @@ public class RefreshableTargetSourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void testRefreshOverTime() throws Exception {
|
||||
CountingRefreshableTargetSource ts = new CountingRefreshableTargetSource(true);
|
||||
ts.setRefreshCheckDelay(100);
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -59,7 +59,8 @@ public abstract aspect AbstractTransactionAspect extends TransactionAspectSuppor
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
clearTransactionManagerCache(); // An aspect is basically a singleton
|
||||
// An aspect is basically a singleton -> cleanup on destruction
|
||||
clearTransactionManagerCache();
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AnnotationAsyncExecutionAspect}.
|
||||
@@ -46,7 +46,7 @@ import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public class AnnotationAsyncExecutionAspectTests {
|
||||
|
||||
private static final long WAIT_TIME = 1000; //milliseconds
|
||||
|
||||
@@ -25,6 +25,7 @@ sourceSets {
|
||||
compileGroovy {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
options.compilerArgs += "-Werror"
|
||||
}
|
||||
|
||||
// This module also builds Kotlin code and the compileKotlin task naturally depends on
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
||||
|
||||
/**
|
||||
* Benchmark for {@link AbstractPropertyAccessor} use on beans.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
public class AbstractPropertyAccessorBenchmark {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class BenchmarkState {
|
||||
|
||||
@Param({"DirectFieldAccessor", "BeanWrapper"})
|
||||
public String accessor;
|
||||
|
||||
@Param({"none", "stringTrimmer", "numberOnPath", "numberOnNestedPath", "numberOnType"})
|
||||
public String customEditor;
|
||||
|
||||
public int[] input;
|
||||
|
||||
public PrimitiveArrayBean target;
|
||||
|
||||
public AbstractPropertyAccessor propertyAccessor;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.target = new PrimitiveArrayBean();
|
||||
this.input = new int[1024];
|
||||
if (this.accessor.equals("DirectFieldAccessor")) {
|
||||
this.propertyAccessor = new DirectFieldAccessor(this.target);
|
||||
}
|
||||
else {
|
||||
this.propertyAccessor = new BeanWrapperImpl(this.target);
|
||||
}
|
||||
switch (this.customEditor) {
|
||||
case "stringTrimmer":
|
||||
this.propertyAccessor.registerCustomEditor(String.class, new StringTrimmerEditor(false));
|
||||
break;
|
||||
case "numberOnPath":
|
||||
this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", new CustomNumberEditor(Integer.class, false));
|
||||
break;
|
||||
case "numberOnNestedPath":
|
||||
this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", new CustomNumberEditor(Integer.class, false));
|
||||
break;
|
||||
case "numberOnType":
|
||||
this.propertyAccessor.registerCustomEditor(int.class, new CustomNumberEditor(Integer.class, false));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public PrimitiveArrayBean setPropertyValue(BenchmarkState state) {
|
||||
state.propertyAccessor.setPropertyValue("array", state.input);
|
||||
return state.target;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class PrimitiveArrayBean {
|
||||
|
||||
private int[] array;
|
||||
|
||||
public int[] getArray() {
|
||||
return this.array;
|
||||
}
|
||||
|
||||
public void setArray(int[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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
|
||||
*
|
||||
* https://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.beans.factory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
|
||||
import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifiedResource;
|
||||
|
||||
/**
|
||||
* Benchmark for creating prototype beans in a concurrent fashion.
|
||||
* This benchmark requires to customize the number of worker threads {@code -t <int>} on the
|
||||
* CLI when running this particular benchmark to leverage concurrency.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
public class ConcurrentBeanFactoryBenchmark {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class BenchmarkState {
|
||||
|
||||
public DefaultListableBeanFactory factory;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.factory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(
|
||||
qualifiedResource(ConcurrentBeanFactoryBenchmark.class, "context.xml"));
|
||||
|
||||
this.factory.addPropertyEditorRegistrar(
|
||||
registry -> registry.registerCustomEditor(Date.class,
|
||||
new CustomDateEditor(new SimpleDateFormat("yyyy/MM/dd"), false)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void concurrentBeanCreation(BenchmarkState state, Blackhole bh) {
|
||||
bh.consume(state.factory.getBean("bean1"));
|
||||
bh.consume(state.factory.getBean("bean2"));
|
||||
}
|
||||
|
||||
|
||||
public static class ConcurrentBean {
|
||||
|
||||
private Date date;
|
||||
|
||||
public Date getDate() {
|
||||
return this.date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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
|
||||
*
|
||||
* https://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.beans.factory;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.LifecycleBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
/**
|
||||
* Benchmark for retrieving various bean types from the {@link DefaultListableBeanFactory}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
public class DefaultListableBeanFactoryBenchmark {
|
||||
|
||||
public static class Shared {
|
||||
public DefaultListableBeanFactory beanFactory;
|
||||
}
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class PrototypeCreationState extends Shared {
|
||||
|
||||
@Param({"simple", "dependencyCheck", "constructor", "constructorArgument", "properties", "resolvedProperties"})
|
||||
public String mode;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
|
||||
switch (this.mode) {
|
||||
case "simple":
|
||||
break;
|
||||
case "dependencyCheck":
|
||||
rbd = new RootBeanDefinition(LifecycleBean.class);
|
||||
rbd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
|
||||
this.beanFactory.addBeanPostProcessor(new LifecycleBean.PostProcessor());
|
||||
break;
|
||||
case "constructor":
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue("juergen");
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue("99");
|
||||
break;
|
||||
case "constructorArgument":
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("spouse"));
|
||||
this.beanFactory.registerBeanDefinition("test", rbd);
|
||||
this.beanFactory.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
|
||||
break;
|
||||
case "properties":
|
||||
rbd.getPropertyValues().add("name", "juergen");
|
||||
rbd.getPropertyValues().add("age", "99");
|
||||
break;
|
||||
case "resolvedProperties":
|
||||
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
|
||||
this.beanFactory.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
|
||||
break;
|
||||
}
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
this.beanFactory.registerBeanDefinition("test", rbd);
|
||||
this.beanFactory.freezeConfiguration();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object prototypeCreation(PrototypeCreationState state) {
|
||||
return state.beanFactory.getBean("test");
|
||||
}
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class SingletonLookupState extends Shared {
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
this.beanFactory.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
this.beanFactory.freezeConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object singletLookup(SingletonLookupState state) {
|
||||
return state.beanFactory.getBean("test");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object singletLookupByType(SingletonLookupState state) {
|
||||
return state.beanFactory.getBean(TestBean.class);
|
||||
}
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class SingletonLookupManyBeansState extends Shared {
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
this.beanFactory.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
this.beanFactory.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
|
||||
}
|
||||
this.beanFactory.freezeConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
// See SPR-6870
|
||||
@Benchmark
|
||||
public Object singletLookupByTypeManyBeans(SingletonLookupState state) {
|
||||
return state.beanFactory.getBean(B.class);
|
||||
}
|
||||
|
||||
static class A {
|
||||
}
|
||||
|
||||
static class B {
|
||||
}
|
||||
|
||||
}
|
||||
+6
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -422,9 +422,12 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw createNotWritablePropertyException(tokens.canonicalName);
|
||||
if (this.suppressNotWritablePropertyException) {
|
||||
// Optimization for common ignoreUnknown=true scenario since the
|
||||
// exception would be caught and swallowed higher up anyway...
|
||||
return;
|
||||
}
|
||||
throw createNotWritablePropertyException(tokens.canonicalName);
|
||||
}
|
||||
|
||||
Object oldValue = null;
|
||||
|
||||
+33
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -40,6 +40,8 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
|
||||
private boolean autoGrowNestedPaths = false;
|
||||
|
||||
boolean suppressNotWritablePropertyException = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void setExtractOldValueForEditor(boolean extractOldValueForEditor) {
|
||||
@@ -89,30 +91,41 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
List<PropertyAccessException> propertyAccessExceptions = null;
|
||||
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
|
||||
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
|
||||
for (PropertyValue pv : propertyValues) {
|
||||
try {
|
||||
// This method may throw any BeansException, which won't be caught
|
||||
|
||||
if (ignoreUnknown) {
|
||||
this.suppressNotWritablePropertyException = true;
|
||||
}
|
||||
try {
|
||||
for (PropertyValue pv : propertyValues) {
|
||||
// setPropertyValue may throw any BeansException, which won't be caught
|
||||
// here, if there is a critical failure such as no matching field.
|
||||
// We can attempt to deal only with less serious exceptions.
|
||||
setPropertyValue(pv);
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
if (!ignoreUnknown) {
|
||||
throw ex;
|
||||
try {
|
||||
setPropertyValue(pv);
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
catch (NullValueInNestedPathException ex) {
|
||||
if (!ignoreInvalid) {
|
||||
throw ex;
|
||||
catch (NotWritablePropertyException ex) {
|
||||
if (!ignoreUnknown) {
|
||||
throw ex;
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
catch (PropertyAccessException ex) {
|
||||
if (propertyAccessExceptions == null) {
|
||||
propertyAccessExceptions = new ArrayList<>();
|
||||
catch (NullValueInNestedPathException ex) {
|
||||
if (!ignoreInvalid) {
|
||||
throw ex;
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
propertyAccessExceptions.add(ex);
|
||||
catch (PropertyAccessException ex) {
|
||||
if (propertyAccessExceptions == null) {
|
||||
propertyAccessExceptions = new ArrayList<>();
|
||||
}
|
||||
propertyAccessExceptions.add(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (ignoreUnknown) {
|
||||
this.suppressNotWritablePropertyException = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -43,12 +44,15 @@ import kotlin.reflect.jvm.ReflectJvmMapping;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -73,6 +77,9 @@ public abstract class BeanUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BeanUtils.class);
|
||||
|
||||
private static final ParameterNameDiscoverer parameterNameDiscoverer =
|
||||
new DefaultParameterNameDiscoverer();
|
||||
|
||||
private static final Set<Class<?>> unknownEditorTypes =
|
||||
Collections.newSetFromMap(new ConcurrentReferenceHashMap<>(64));
|
||||
|
||||
@@ -219,6 +226,35 @@ public abstract class BeanUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resolvable constructor for the provided class, either a primary constructor
|
||||
* or single public constructor or simply a default constructor. Callers have to be
|
||||
* prepared to resolve arguments for the returned constructor's parameters, if any.
|
||||
* @param clazz the class to check
|
||||
* @since 5.3
|
||||
* @see #findPrimaryConstructor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Constructor<T> getResolvableConstructor(Class<T> clazz) {
|
||||
Constructor<T> ctor = findPrimaryConstructor(clazz);
|
||||
if (ctor == null) {
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
ctor = (Constructor<T>) ctors[0];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ctor = clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("No primary or single public constructor found for " +
|
||||
clazz + " - and no default constructor found either");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary constructor of the provided class. For Kotlin classes, this
|
||||
* returns the Java constructor corresponding to the Kotlin primary constructor
|
||||
@@ -442,8 +478,7 @@ public abstract class BeanUtils {
|
||||
* @throws BeansException if PropertyDescriptor look fails
|
||||
*/
|
||||
public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws BeansException {
|
||||
CachedIntrospectionResults cr = CachedIntrospectionResults.forClass(clazz);
|
||||
return cr.getPropertyDescriptors();
|
||||
return CachedIntrospectionResults.forClass(clazz).getPropertyDescriptors();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,11 +489,8 @@ public abstract class BeanUtils {
|
||||
* @throws BeansException if PropertyDescriptor lookup fails
|
||||
*/
|
||||
@Nullable
|
||||
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName)
|
||||
throws BeansException {
|
||||
|
||||
CachedIntrospectionResults cr = CachedIntrospectionResults.forClass(clazz);
|
||||
return cr.getPropertyDescriptor(propertyName);
|
||||
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName) throws BeansException {
|
||||
return CachedIntrospectionResults.forClass(clazz).getPropertyDescriptor(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,6 +619,26 @@ public abstract class BeanUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine required parameter names for the given constructor,
|
||||
* considering the JavaBeans {@link ConstructorProperties} annotation
|
||||
* as well as Spring's {@link DefaultParameterNameDiscoverer}.
|
||||
* @param ctor the constructor to find parameter names for
|
||||
* @return the parameter names (matching the constructor's parameter count)
|
||||
* @throws IllegalStateException if the parameter names are not resolvable
|
||||
* @since 5.3
|
||||
* @see ConstructorProperties
|
||||
* @see DefaultParameterNameDiscoverer
|
||||
*/
|
||||
public static String[] getParameterNames(Constructor<?> ctor) {
|
||||
ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
|
||||
String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
|
||||
Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
|
||||
Assert.state(paramNames.length == ctor.getParameterCount(),
|
||||
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given type represents a "simple" property: a simple value
|
||||
* type or an array of simple value types.
|
||||
@@ -792,7 +844,7 @@ public abstract class BeanUtils {
|
||||
}
|
||||
|
||||
List<KParameter> parameters = kotlinConstructor.getParameters();
|
||||
Map<KParameter, Object> argParameters = new HashMap<>(parameters.size());
|
||||
Map<KParameter, Object> argParameters = CollectionUtils.newHashMap(parameters.size());
|
||||
Assert.isTrue(args.length <= parameters.size(),
|
||||
"Number of provided arguments should be less of equals than number of constructor parameters");
|
||||
for (int i = 0 ; i < args.length ; i++) {
|
||||
|
||||
+63
-21
@@ -20,7 +20,10 @@ import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -92,6 +95,8 @@ public final class CachedIntrospectionResults {
|
||||
*/
|
||||
public static final String IGNORE_BEANINFO_PROPERTY_NAME = "spring.beaninfo.ignore";
|
||||
|
||||
private static final PropertyDescriptor[] EMPTY_PROPERTY_DESCRIPTOR_ARRAY = {};
|
||||
|
||||
|
||||
private static final boolean shouldIntrospectorIgnoreBeaninfoClasses =
|
||||
SpringProperties.getFlag(IGNORE_BEANINFO_PROPERTY_NAME);
|
||||
@@ -253,7 +258,7 @@ public final class CachedIntrospectionResults {
|
||||
private final BeanInfo beanInfo;
|
||||
|
||||
/** PropertyDescriptor objects keyed by property name String. */
|
||||
private final Map<String, PropertyDescriptor> propertyDescriptorCache;
|
||||
private final Map<String, PropertyDescriptor> propertyDescriptors;
|
||||
|
||||
/** TypeDescriptor objects keyed by PropertyDescriptor. */
|
||||
private final ConcurrentMap<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
|
||||
@@ -274,7 +279,9 @@ public final class CachedIntrospectionResults {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Caching PropertyDescriptors for class [" + beanClass.getName() + "]");
|
||||
}
|
||||
this.propertyDescriptorCache = new LinkedHashMap<>();
|
||||
this.propertyDescriptors = new LinkedHashMap<>();
|
||||
|
||||
Set<String> readMethodNames = new HashSet<>();
|
||||
|
||||
// This call is slow so we do it once.
|
||||
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
|
||||
@@ -291,17 +298,26 @@ public final class CachedIntrospectionResults {
|
||||
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
|
||||
}
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||
this.propertyDescriptors.put(pd.getName(), pd);
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
readMethodNames.add(readMethod.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly check implemented interfaces for setter/getter methods as well,
|
||||
// in particular for Java 8 default methods...
|
||||
Class<?> currClass = beanClass;
|
||||
while (currClass != null && currClass != Object.class) {
|
||||
introspectInterfaces(beanClass, currClass);
|
||||
introspectInterfaces(beanClass, currClass, readMethodNames);
|
||||
currClass = currClass.getSuperclass();
|
||||
}
|
||||
|
||||
// Check for record-style accessors without prefix: e.g. "lastName()"
|
||||
// - accessor method directly referring to instance field of same name
|
||||
// - same convention for component accessors of Java 15 record classes
|
||||
introspectPlainAccessors(beanClass, readMethodNames);
|
||||
|
||||
this.typeDescriptorCache = new ConcurrentReferenceHashMap<>();
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
@@ -309,24 +325,58 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
}
|
||||
|
||||
private void introspectInterfaces(Class<?> beanClass, Class<?> currClass) throws IntrospectionException {
|
||||
private void introspectInterfaces(Class<?> beanClass, Class<?> currClass, Set<String> readMethodNames)
|
||||
throws IntrospectionException {
|
||||
|
||||
for (Class<?> ifc : currClass.getInterfaces()) {
|
||||
if (!ClassUtils.isJavaLanguageInterface(ifc)) {
|
||||
for (PropertyDescriptor pd : getBeanInfo(ifc).getPropertyDescriptors()) {
|
||||
PropertyDescriptor existingPd = this.propertyDescriptorCache.get(pd.getName());
|
||||
PropertyDescriptor existingPd = this.propertyDescriptors.get(pd.getName());
|
||||
if (existingPd == null ||
|
||||
(existingPd.getReadMethod() == null && pd.getReadMethod() != null)) {
|
||||
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
|
||||
// against a declared read method, so we prefer read method descriptors here.
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||
this.propertyDescriptors.put(pd.getName(), pd);
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
readMethodNames.add(readMethod.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
introspectInterfaces(ifc, ifc);
|
||||
introspectInterfaces(ifc, ifc, readMethodNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void introspectPlainAccessors(Class<?> beanClass, Set<String> readMethodNames)
|
||||
throws IntrospectionException {
|
||||
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (!this.propertyDescriptors.containsKey(method.getName()) &&
|
||||
!readMethodNames.contains((method.getName())) && isPlainAccessor(method)) {
|
||||
this.propertyDescriptors.put(method.getName(),
|
||||
new GenericTypeAwarePropertyDescriptor(beanClass, method.getName(), method, null, null));
|
||||
readMethodNames.add(method.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPlainAccessor(Method method) {
|
||||
if (method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// Accessor method referring to instance field of same name?
|
||||
method.getDeclaringClass().getDeclaredField(method.getName());
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeanInfo getBeanInfo() {
|
||||
return this.beanInfo;
|
||||
@@ -338,27 +388,19 @@ public final class CachedIntrospectionResults {
|
||||
|
||||
@Nullable
|
||||
PropertyDescriptor getPropertyDescriptor(String name) {
|
||||
PropertyDescriptor pd = this.propertyDescriptorCache.get(name);
|
||||
PropertyDescriptor pd = this.propertyDescriptors.get(name);
|
||||
if (pd == null && StringUtils.hasLength(name)) {
|
||||
// Same lenient fallback checking as in Property...
|
||||
pd = this.propertyDescriptorCache.get(StringUtils.uncapitalize(name));
|
||||
pd = this.propertyDescriptors.get(StringUtils.uncapitalize(name));
|
||||
if (pd == null) {
|
||||
pd = this.propertyDescriptorCache.get(StringUtils.capitalize(name));
|
||||
pd = this.propertyDescriptors.get(StringUtils.capitalize(name));
|
||||
}
|
||||
}
|
||||
return (pd == null || pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
|
||||
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
|
||||
return pd;
|
||||
}
|
||||
|
||||
PropertyDescriptor[] getPropertyDescriptors() {
|
||||
PropertyDescriptor[] pds = new PropertyDescriptor[this.propertyDescriptorCache.size()];
|
||||
int i = 0;
|
||||
for (PropertyDescriptor pd : this.propertyDescriptorCache.values()) {
|
||||
pds[i] = (pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
|
||||
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
|
||||
i++;
|
||||
}
|
||||
return pds;
|
||||
return this.propertyDescriptors.values().toArray(EMPTY_PROPERTY_DESCRIPTOR_ARRAY);
|
||||
}
|
||||
|
||||
private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class<?> beanClass, PropertyDescriptor pd) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -92,8 +92,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
|
||||
@Override
|
||||
protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) {
|
||||
PropertyMatches matches = PropertyMatches.forField(propertyName, getRootClass());
|
||||
throw new NotWritablePropertyException(
|
||||
getRootClass(), getNestedPath() + propertyName,
|
||||
throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName,
|
||||
matches.buildErrorMessage(), matches.getPossibleMatches());
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -60,12 +60,13 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
@Nullable
|
||||
private Class<?> propertyType;
|
||||
|
||||
@Nullable
|
||||
private final Class<?> propertyEditorClass;
|
||||
|
||||
|
||||
public GenericTypeAwarePropertyDescriptor(Class<?> beanClass, String propertyName,
|
||||
@Nullable Method readMethod, @Nullable Method writeMethod, Class<?> propertyEditorClass)
|
||||
throws IntrospectionException {
|
||||
@Nullable Method readMethod, @Nullable Method writeMethod,
|
||||
@Nullable Class<?> propertyEditorClass) throws IntrospectionException {
|
||||
|
||||
super(propertyName, null, null);
|
||||
this.beanClass = beanClass;
|
||||
@@ -156,6 +157,7 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getPropertyEditorClass() {
|
||||
return this.propertyEditorClass;
|
||||
}
|
||||
|
||||
+4
-5
@@ -644,21 +644,20 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
}
|
||||
synchronized (this) {
|
||||
if (!this.cached) {
|
||||
Object cachedFieldValue = null;
|
||||
if (value != null || this.required) {
|
||||
this.cachedFieldValue = desc;
|
||||
cachedFieldValue = desc;
|
||||
registerDependentBeans(beanName, autowiredBeanNames);
|
||||
if (autowiredBeanNames.size() == 1) {
|
||||
String autowiredBeanName = autowiredBeanNames.iterator().next();
|
||||
if (beanFactory.containsBean(autowiredBeanName) &&
|
||||
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
|
||||
this.cachedFieldValue = new ShortcutDependencyDescriptor(
|
||||
cachedFieldValue = new ShortcutDependencyDescriptor(
|
||||
desc, autowiredBeanName, field.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.cachedFieldValue = null;
|
||||
}
|
||||
this.cachedFieldValue = cachedFieldValue;
|
||||
this.cached = true;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-14
@@ -26,9 +26,6 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
@@ -69,8 +66,6 @@ public class InjectionMetadata {
|
||||
};
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private final Class<?> targetClass;
|
||||
|
||||
private final Collection<InjectedElement> injectedElements;
|
||||
@@ -110,9 +105,6 @@ public class InjectionMetadata {
|
||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||
checkedElements.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.checkedElements = checkedElements;
|
||||
@@ -124,9 +116,6 @@ public class InjectionMetadata {
|
||||
(checkedElements != null ? checkedElements : this.injectedElements);
|
||||
if (!elementsToIterate.isEmpty()) {
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, pvs);
|
||||
}
|
||||
}
|
||||
@@ -152,12 +141,12 @@ public class InjectionMetadata {
|
||||
* Return an {@code InjectionMetadata} instance, possibly for empty elements.
|
||||
* @param elements the elements to inject (possibly empty)
|
||||
* @param clazz the target class
|
||||
* @return a new {@link #InjectionMetadata(Class, Collection)} instance,
|
||||
* or {@link #EMPTY} in case of no elements
|
||||
* @return a new {@link #InjectionMetadata(Class, Collection)} instance
|
||||
* @since 5.2
|
||||
*/
|
||||
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
|
||||
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
|
||||
return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
|
||||
new InjectionMetadata(clazz, elements));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -40,7 +40,6 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link AutowireCandidateResolver} implementation that matches bean definition qualifiers
|
||||
@@ -188,7 +187,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
foundMeta = true;
|
||||
// Only accept fallback match if @Qualifier annotation has a value...
|
||||
// Otherwise it is just a marker for a custom qualifier annotation.
|
||||
if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
|
||||
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
|
||||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -164,10 +164,10 @@ public class ConstructorArgumentValues {
|
||||
Assert.isTrue(index >= 0, "Index must not be negative");
|
||||
ValueHolder valueHolder = this.indexedArgumentValues.get(index);
|
||||
if (valueHolder != null &&
|
||||
(valueHolder.getType() == null ||
|
||||
(requiredType != null && ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) &&
|
||||
(valueHolder.getName() == null || "".equals(requiredName) ||
|
||||
(requiredName != null && requiredName.equals(valueHolder.getName())))) {
|
||||
(valueHolder.getType() == null || (requiredType != null &&
|
||||
ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) &&
|
||||
(valueHolder.getName() == null || (requiredName != null &&
|
||||
(requiredName.isEmpty() || requiredName.equals(valueHolder.getName()))))) {
|
||||
return valueHolder;
|
||||
}
|
||||
return null;
|
||||
@@ -277,17 +277,19 @@ public class ConstructorArgumentValues {
|
||||
* @return the ValueHolder for the argument, or {@code null} if none found
|
||||
*/
|
||||
@Nullable
|
||||
public ValueHolder getGenericArgumentValue(@Nullable Class<?> requiredType, @Nullable String requiredName, @Nullable Set<ValueHolder> usedValueHolders) {
|
||||
public ValueHolder getGenericArgumentValue(@Nullable Class<?> requiredType, @Nullable String requiredName,
|
||||
@Nullable Set<ValueHolder> usedValueHolders) {
|
||||
|
||||
for (ValueHolder valueHolder : this.genericArgumentValues) {
|
||||
if (usedValueHolders != null && usedValueHolders.contains(valueHolder)) {
|
||||
continue;
|
||||
}
|
||||
if (valueHolder.getName() != null && !"".equals(requiredName) &&
|
||||
(requiredName == null || !valueHolder.getName().equals(requiredName))) {
|
||||
if (valueHolder.getName() != null && (requiredName == null ||
|
||||
(!requiredName.isEmpty() && !requiredName.equals(valueHolder.getName())))) {
|
||||
continue;
|
||||
}
|
||||
if (valueHolder.getType() != null &&
|
||||
(requiredType == null || !ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) {
|
||||
if (valueHolder.getType() != null && (requiredType == null ||
|
||||
!ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) {
|
||||
continue;
|
||||
}
|
||||
if (requiredType != null && valueHolder.getType() == null && valueHolder.getName() == null &&
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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,13 +16,13 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Simple factory for shared Map instances. Allows for central setup
|
||||
@@ -85,7 +85,7 @@ public class MapFactoryBean extends AbstractFactoryBean<Map<Object, Object>> {
|
||||
result = BeanUtils.instantiateClass(this.targetMapClass);
|
||||
}
|
||||
else {
|
||||
result = new LinkedHashMap<>(this.sourceMap.size());
|
||||
result = CollectionUtils.newLinkedHashMap(this.sourceMap.size());
|
||||
}
|
||||
Class<?> keyType = null;
|
||||
Class<?> valueType = null;
|
||||
|
||||
@@ -351,6 +351,7 @@ public abstract class YamlProcessor {
|
||||
/**
|
||||
* Callback interface used to process the YAML parsing results.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface MatchCallback {
|
||||
|
||||
/**
|
||||
@@ -367,6 +368,7 @@ public abstract class YamlProcessor {
|
||||
/**
|
||||
* Strategy interface used to test if properties match.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DocumentMatcher {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2020 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,11 +24,11 @@ package org.springframework.beans.factory.parsing;
|
||||
*/
|
||||
public class BeanEntry implements ParseState.Entry {
|
||||
|
||||
private String beanDefinitionName;
|
||||
private final String beanDefinitionName;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link BeanEntry} class.
|
||||
* Create a new {@code BeanEntry} instance.
|
||||
* @param beanDefinitionName the name of the associated bean definition
|
||||
*/
|
||||
public BeanEntry(String beanDefinitionName) {
|
||||
|
||||
+25
-30
@@ -16,69 +16,63 @@
|
||||
|
||||
package org.springframework.beans.factory.parsing;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Simple {@link LinkedList}-based structure for tracking the logical position during
|
||||
* a parsing process. {@link Entry entries} are added to the LinkedList at
|
||||
* each point during the parse phase in a reader-specific manner.
|
||||
* Simple {@link ArrayDeque}-based structure for tracking the logical position during
|
||||
* a parsing process. {@link Entry entries} are added to the ArrayDeque at each point
|
||||
* during the parse phase in a reader-specific manner.
|
||||
*
|
||||
* <p>Calling {@link #toString()} will render a tree-style view of the current logical
|
||||
* position in the parse phase. This representation is intended for use in
|
||||
* error messages.
|
||||
* position in the parse phase. This representation is intended for use in error messages.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class ParseState {
|
||||
|
||||
/**
|
||||
* Tab character used when rendering the tree-style representation.
|
||||
* Internal {@link ArrayDeque} storage.
|
||||
*/
|
||||
private static final char TAB = '\t';
|
||||
|
||||
/**
|
||||
* Internal {@link LinkedList} storage.
|
||||
*/
|
||||
private final LinkedList<Entry> state;
|
||||
private final ArrayDeque<Entry> state;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code ParseState} with an empty {@link LinkedList}.
|
||||
* Create a new {@code ParseState} with an empty {@link ArrayDeque}.
|
||||
*/
|
||||
public ParseState() {
|
||||
this.state = new LinkedList<>();
|
||||
this.state = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ParseState} whose {@link LinkedList} is a {@link Object#clone clone}
|
||||
* of that of the passed in {@code ParseState}.
|
||||
* Create a new {@code ParseState} whose {@link ArrayDeque} is a clone
|
||||
* of the state in the passed-in {@code ParseState}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private ParseState(ParseState other) {
|
||||
this.state = (LinkedList<Entry>) other.state.clone();
|
||||
this.state = other.state.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new {@link Entry} to the {@link LinkedList}.
|
||||
* Add a new {@link Entry} to the {@link ArrayDeque}.
|
||||
*/
|
||||
public void push(Entry entry) {
|
||||
this.state.push(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an {@link Entry} from the {@link LinkedList}.
|
||||
* Remove an {@link Entry} from the {@link ArrayDeque}.
|
||||
*/
|
||||
public void pop() {
|
||||
this.state.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link Entry} currently at the top of the {@link LinkedList} or
|
||||
* {@code null} if the {@link LinkedList} is empty.
|
||||
* Return the {@link Entry} currently at the top of the {@link ArrayDeque} or
|
||||
* {@code null} if the {@link ArrayDeque} is empty.
|
||||
*/
|
||||
@Nullable
|
||||
public Entry peek() {
|
||||
@@ -99,16 +93,18 @@ public final class ParseState {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int x = 0; x < this.state.size(); x++) {
|
||||
if (x > 0) {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
int i = 0;
|
||||
for (ParseState.Entry entry : this.state) {
|
||||
if (i > 0) {
|
||||
sb.append('\n');
|
||||
for (int y = 0; y < x; y++) {
|
||||
sb.append(TAB);
|
||||
for (int j = 0; j < i; j++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
sb.append("-> ");
|
||||
}
|
||||
sb.append(this.state.get(x));
|
||||
sb.append(entry);
|
||||
i++;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -118,7 +114,6 @@ public final class ParseState {
|
||||
* Marker interface for entries into the {@link ParseState}.
|
||||
*/
|
||||
public interface Entry {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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,14 +30,12 @@ public class PropertyEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link PropertyEntry} class.
|
||||
* Create a new {@code PropertyEntry} instance.
|
||||
* @param name the name of the JavaBean property represented by this instance
|
||||
* @throws IllegalArgumentException if the supplied {@code name} is {@code null}
|
||||
* or consists wholly of whitespace
|
||||
*/
|
||||
public PropertyEntry(String name) {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
throw new IllegalArgumentException("Invalid property name '" + name + "'.");
|
||||
throw new IllegalArgumentException("Invalid property name '" + name + "'");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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,16 +26,21 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class QualifierEntry implements ParseState.Entry {
|
||||
|
||||
private String typeName;
|
||||
private final String typeName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code QualifierEntry} instance.
|
||||
* @param typeName the name of the qualifier type
|
||||
*/
|
||||
public QualifierEntry(String typeName) {
|
||||
if (!StringUtils.hasText(typeName)) {
|
||||
throw new IllegalArgumentException("Invalid qualifier type '" + typeName + "'.");
|
||||
throw new IllegalArgumentException("Invalid qualifier type '" + typeName + "'");
|
||||
}
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Qualifier '" + this.typeName + "'";
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.serviceloader;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ServiceListFactoryBean extends AbstractServiceLoaderBasedFactoryBea
|
||||
|
||||
@Override
|
||||
protected Object getObjectToExpose(ServiceLoader<?> serviceLoader) {
|
||||
List<Object> result = new LinkedList<>();
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (Object loaderObject : serviceLoader) {
|
||||
result.add(loaderObject);
|
||||
}
|
||||
|
||||
+9
-7
@@ -300,9 +300,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
markBeanAsCreated(beanName);
|
||||
}
|
||||
|
||||
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
|
||||
.tag("beanName", name);
|
||||
try {
|
||||
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
|
||||
.tag("beanName", name);
|
||||
if (requiredType != null) {
|
||||
beanCreation.tag("beanType", requiredType::toString);
|
||||
}
|
||||
@@ -383,12 +383,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
throw new ScopeNotActiveException(beanName, scopeName, ex);
|
||||
}
|
||||
}
|
||||
beanCreation.end();
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
beanCreation.tag("exception", ex.getClass().toString());
|
||||
beanCreation.tag("message", String.valueOf(ex.getMessage()));
|
||||
cleanupAfterBeanCreationFailure(beanName);
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
beanCreation.end();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if required type matches the type of the actual bean instance.
|
||||
@@ -1284,10 +1288,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @param registry the PropertyEditorRegistry to initialize
|
||||
*/
|
||||
protected void registerCustomEditors(PropertyEditorRegistry registry) {
|
||||
PropertyEditorRegistrySupport registrySupport =
|
||||
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
|
||||
if (registrySupport != null) {
|
||||
registrySupport.useConfigValueEditors();
|
||||
if (registry instanceof PropertyEditorRegistrySupport) {
|
||||
((PropertyEditorRegistrySupport) registry).useConfigValueEditors();
|
||||
}
|
||||
if (!this.propertyEditorRegistrars.isEmpty()) {
|
||||
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
|
||||
|
||||
+2
-2
@@ -18,7 +18,6 @@ package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -42,6 +41,7 @@ import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.TypedStringValue;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -447,7 +447,7 @@ class BeanDefinitionValueResolver {
|
||||
* For each element in the managed map, resolve reference if necessary.
|
||||
*/
|
||||
private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {
|
||||
Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());
|
||||
Map<Object, Object> resolved = CollectionUtils.newLinkedHashMap(mm.size());
|
||||
mm.forEach((key, value) -> {
|
||||
Object resolvedKey = resolveValueIfNecessary(argName, key);
|
||||
Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -238,8 +238,10 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
Assert.state(lo != null, "LookupOverride not found");
|
||||
Object[] argsToUse = (args.length > 0 ? args : null); // if no-arg, don't insist on args at all
|
||||
if (StringUtils.hasText(lo.getBeanName())) {
|
||||
return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
|
||||
Object bean = (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
|
||||
this.owner.getBean(lo.getBeanName()));
|
||||
// Detect package-protected NullBean instance through equals(null) check
|
||||
return (bean.equals(null) ? null : bean);
|
||||
}
|
||||
else {
|
||||
return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
|
||||
|
||||
+13
-10
@@ -24,12 +24,13 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -66,6 +67,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Delegate for resolving constructors and factory methods.
|
||||
*
|
||||
* <p>Performs constructor resolution through argument matching.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
@@ -84,7 +86,7 @@ class ConstructorResolver {
|
||||
private static final Object[] EMPTY_ARGS = new Object[0];
|
||||
|
||||
/**
|
||||
* Marker for autowired arguments in a cached argument array, to be later replaced
|
||||
* Marker for autowired arguments in a cached argument array, to be replaced
|
||||
* by a {@linkplain #resolveAutowiredArgument resolved autowired argument}.
|
||||
*/
|
||||
private static final Object autowiredArgumentMarker = new Object();
|
||||
@@ -148,7 +150,7 @@ class ConstructorResolver {
|
||||
}
|
||||
}
|
||||
if (argsToResolve != null) {
|
||||
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
|
||||
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +201,7 @@ class ConstructorResolver {
|
||||
AutowireUtils.sortConstructors(candidates);
|
||||
int minTypeDiffWeight = Integer.MAX_VALUE;
|
||||
Set<Constructor<?>> ambiguousConstructors = null;
|
||||
LinkedList<UnsatisfiedDependencyException> causes = null;
|
||||
Deque<UnsatisfiedDependencyException> causes = null;
|
||||
|
||||
for (Constructor<?> candidate : candidates) {
|
||||
int parameterCount = candidate.getParameterCount();
|
||||
@@ -233,7 +235,7 @@ class ConstructorResolver {
|
||||
}
|
||||
// Swallow and try next constructor.
|
||||
if (causes == null) {
|
||||
causes = new LinkedList<>();
|
||||
causes = new ArrayDeque<>(1);
|
||||
}
|
||||
causes.add(ex);
|
||||
continue;
|
||||
@@ -409,6 +411,7 @@ class ConstructorResolver {
|
||||
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
|
||||
throw new ImplicitlyAppearedSingletonException();
|
||||
}
|
||||
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
|
||||
factoryClass = factoryBean.getClass();
|
||||
isStatic = false;
|
||||
}
|
||||
@@ -443,7 +446,7 @@ class ConstructorResolver {
|
||||
}
|
||||
}
|
||||
if (argsToResolve != null) {
|
||||
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
|
||||
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,7 +514,7 @@ class ConstructorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
LinkedList<UnsatisfiedDependencyException> causes = null;
|
||||
Deque<UnsatisfiedDependencyException> causes = null;
|
||||
|
||||
for (Method candidate : candidates) {
|
||||
int parameterCount = candidate.getParameterCount();
|
||||
@@ -544,7 +547,7 @@ class ConstructorResolver {
|
||||
}
|
||||
// Swallow and try next overloaded factory method.
|
||||
if (causes == null) {
|
||||
causes = new LinkedList<>();
|
||||
causes = new ArrayDeque<>(1);
|
||||
}
|
||||
causes.add(ex);
|
||||
continue;
|
||||
@@ -815,7 +818,7 @@ class ConstructorResolver {
|
||||
* Resolve the prepared arguments stored in the given bean definition.
|
||||
*/
|
||||
private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
|
||||
Executable executable, Object[] argsToResolve, boolean fallback) {
|
||||
Executable executable, Object[] argsToResolve) {
|
||||
|
||||
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
|
||||
TypeConverter converter = (customConverter != null ? customConverter : bw);
|
||||
@@ -828,7 +831,7 @@ class ConstructorResolver {
|
||||
Object argValue = argsToResolve[argIndex];
|
||||
MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
|
||||
if (argValue == autowiredArgumentMarker) {
|
||||
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, fallback);
|
||||
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, true);
|
||||
}
|
||||
else if (argValue instanceof BeanMetadataElement) {
|
||||
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
|
||||
|
||||
+6
-6
@@ -33,7 +33,6 @@ import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -81,6 +80,7 @@ import org.springframework.core.metrics.StartupStep;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.CompositeIterator;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -476,7 +476,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
Map<String, T> matchingBeans = new LinkedHashMap<>(beanNames.length);
|
||||
Map<String, T> matchingBeans = CollectionUtils.newLinkedHashMap(beanNames.length);
|
||||
for (String beanName : beanNames) {
|
||||
Object beanInstance = getBean(beanName);
|
||||
if (!(beanInstance instanceof NullBean)) {
|
||||
@@ -665,7 +665,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {
|
||||
|
||||
String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
|
||||
Map<String, T> result = new LinkedHashMap<>(beanNames.length);
|
||||
Map<String, T> result = CollectionUtils.newLinkedHashMap(beanNames.length);
|
||||
for (String beanName : beanNames) {
|
||||
try {
|
||||
Object beanInstance = getBean(beanName);
|
||||
@@ -715,7 +715,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
|
||||
String[] beanNames = getBeanNamesForAnnotation(annotationType);
|
||||
Map<String, Object> result = new LinkedHashMap<>(beanNames.length);
|
||||
Map<String, Object> result = CollectionUtils.newLinkedHashMap(beanNames.length);
|
||||
for (String beanName : beanNames) {
|
||||
Object beanInstance = getBean(beanName);
|
||||
if (!(beanInstance instanceof NullBean)) {
|
||||
@@ -1235,7 +1235,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
|
||||
}
|
||||
else if (candidateNames.length > 1) {
|
||||
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
|
||||
Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
|
||||
for (String beanName : candidateNames) {
|
||||
if (containsSingleton(beanName) && args == null) {
|
||||
Object beanInstance = getBean(beanName);
|
||||
@@ -1532,7 +1532,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||
this, requiredType, true, descriptor.isEager());
|
||||
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
|
||||
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
|
||||
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
|
||||
Class<?> autowiringType = classObjectEntry.getKey();
|
||||
if (autowiringType.isAssignableFrom(requiredType)) {
|
||||
|
||||
+17
-9
@@ -81,7 +81,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
|
||||
|
||||
/** Cache of early singleton objects: bean name to bean instance. */
|
||||
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
|
||||
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
|
||||
|
||||
/** Set of registered singletons, containing the bean names in registration order. */
|
||||
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
|
||||
@@ -178,16 +178,24 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
*/
|
||||
@Nullable
|
||||
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
|
||||
// Quick check for existing instance without full singleton lock
|
||||
Object singletonObject = this.singletonObjects.get(beanName);
|
||||
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
|
||||
synchronized (this.singletonObjects) {
|
||||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||||
if (singletonObject == null && allowEarlyReference) {
|
||||
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
|
||||
if (singletonFactory != null) {
|
||||
singletonObject = singletonFactory.getObject();
|
||||
this.earlySingletonObjects.put(beanName, singletonObject);
|
||||
this.singletonFactories.remove(beanName);
|
||||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||||
if (singletonObject == null && allowEarlyReference) {
|
||||
synchronized (this.singletonObjects) {
|
||||
// Consistent creation of early reference within full singleton lock
|
||||
singletonObject = this.singletonObjects.get(beanName);
|
||||
if (singletonObject == null) {
|
||||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||||
if (singletonObject == null) {
|
||||
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
|
||||
if (singletonFactory != null) {
|
||||
singletonObject = singletonFactory.getObject();
|
||||
this.earlySingletonObjects.put(beanName, singletonObject);
|
||||
this.singletonFactories.remove(beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -449,8 +449,8 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
|
||||
else if (SINGLETON_KEY.equals(property)) {
|
||||
// Spring 1.2 style
|
||||
String val = StringUtils.trimWhitespace((String) entry.getValue());
|
||||
scope = ("".equals(val) || TRUE_VALUE.equals(val) ? BeanDefinition.SCOPE_SINGLETON :
|
||||
BeanDefinition.SCOPE_PROTOTYPE);
|
||||
scope = (!StringUtils.hasLength(val) || TRUE_VALUE.equals(val) ?
|
||||
BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
|
||||
}
|
||||
else if (LAZY_INIT_KEY.equals(property)) {
|
||||
String val = StringUtils.trimWhitespace((String) entry.getValue());
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +17,7 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -39,7 +39,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
|
||||
private final String methodReplacerBeanName;
|
||||
|
||||
private List<String> typeIdentifiers = new LinkedList<>();
|
||||
private final List<String> typeIdentifiers = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
*/
|
||||
public ReplaceOverride(String methodName, String methodReplacerBeanName) {
|
||||
super(methodName);
|
||||
Assert.notNull(methodName, "Method replacer bean name must not be null");
|
||||
Assert.notNull(methodReplacerBeanName, "Method replacer bean name must not be null");
|
||||
this.methodReplacerBeanName = methodReplacerBeanName;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
this.typeIdentifiers.add(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method) {
|
||||
if (!method.getName().equals(getMethodName())) {
|
||||
|
||||
+2
-2
@@ -1523,7 +1523,7 @@ public class BeanDefinitionParserDelegate {
|
||||
* Determine whether the given URI indicates the default namespace.
|
||||
*/
|
||||
public boolean isDefaultNamespace(@Nullable String namespaceUri) {
|
||||
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
|
||||
return !StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1534,7 +1534,7 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
|
||||
private boolean isDefaultValue(String value) {
|
||||
return (DEFAULT_VALUE.equals(value) || "".equals(value));
|
||||
return !StringUtils.hasLength(value) || DEFAULT_VALUE.equals(value);
|
||||
}
|
||||
|
||||
private boolean isCandidateElement(Node node) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -119,7 +119,7 @@ public class URIEditor extends PropertyEditorSupport {
|
||||
setValue(createURI(uri));
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalArgumentException("Invalid URI syntax: " + ex);
|
||||
throw new IllegalArgumentException("Invalid URI syntax: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-69
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -25,7 +25,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -35,11 +34,9 @@ import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
|
||||
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
||||
import org.springframework.beans.support.DerivedFromProtectedBaseBean;
|
||||
@@ -52,17 +49,13 @@ import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.testfixture.Assume;
|
||||
import org.springframework.core.testfixture.EnabledForTestGroups;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.within;
|
||||
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
|
||||
/**
|
||||
* Shared tests for property accessors.
|
||||
@@ -960,60 +953,6 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
assertThat(target.getArray()[1]).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
public void setPrimitiveArrayPropertyLargeMatching() {
|
||||
Assume.notLogging(LogFactory.getLog(AbstractPropertyAccessorTests.class));
|
||||
|
||||
PrimitiveArrayBean target = new PrimitiveArrayBean();
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
int[] input = new int[1024];
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("array1");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
accessor.setPropertyValue("array", input);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(target.getArray().length).isEqualTo(1024);
|
||||
assertThat(target.getArray()[0]).isEqualTo(0);
|
||||
long time1 = sw.getLastTaskTimeMillis();
|
||||
assertThat(sw.getLastTaskTimeMillis() < 100).as("Took too long").isTrue();
|
||||
|
||||
accessor.registerCustomEditor(String.class, new StringTrimmerEditor(false));
|
||||
sw.start("array2");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
accessor.setPropertyValue("array", input);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(sw.getLastTaskTimeMillis() < 125).as("Took too long").isTrue();
|
||||
|
||||
accessor.registerCustomEditor(int.class, "array.somePath", new CustomNumberEditor(Integer.class, false));
|
||||
sw.start("array3");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
accessor.setPropertyValue("array", input);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(sw.getLastTaskTimeMillis() < 100).as("Took too long").isTrue();
|
||||
|
||||
accessor.registerCustomEditor(int.class, "array[0].somePath", new CustomNumberEditor(Integer.class, false));
|
||||
sw.start("array3");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
accessor.setPropertyValue("array", input);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(sw.getLastTaskTimeMillis() < 100).as("Took too long").isTrue();
|
||||
|
||||
accessor.registerCustomEditor(int.class, new CustomNumberEditor(Integer.class, false));
|
||||
sw.start("array4");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
accessor.setPropertyValue("array", input);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(target.getArray().length).isEqualTo(1024);
|
||||
assertThat(target.getArray()[0]).isEqualTo(0);
|
||||
assertThat(sw.getLastTaskTimeMillis() > time1).as("Took too long").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPrimitiveArrayPropertyLargeMatchingWithSpecificEditor() {
|
||||
PrimitiveArrayBean target = new PrimitiveArrayBean();
|
||||
@@ -1072,7 +1011,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
public void setGenericArrayProperty() {
|
||||
SkipReaderStub target = new SkipReaderStub();
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
List<String> values = new LinkedList<>();
|
||||
List<String> values = new ArrayList<>();
|
||||
values.add("1");
|
||||
values.add("2");
|
||||
values.add("3");
|
||||
@@ -1113,7 +1052,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
SortedSet<String> sortedSet = new TreeSet<>();
|
||||
sortedSet.add("sortedSet1");
|
||||
accessor.setPropertyValue("sortedSet", sortedSet);
|
||||
List<String> list = new LinkedList<>();
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("list1");
|
||||
accessor.setPropertyValue("list", list);
|
||||
assertThat(target.getCollection()).isSameAs(coll);
|
||||
@@ -1130,7 +1069,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
Collection<String> coll = new ArrayList<>();
|
||||
coll.add("coll1");
|
||||
accessor.setPropertyValue("collection", coll);
|
||||
List<String> set = new LinkedList<>();
|
||||
List<String> set = new ArrayList<>();
|
||||
set.add("set1");
|
||||
accessor.setPropertyValue("set", set);
|
||||
List<String> sortedSet = new ArrayList<>();
|
||||
@@ -1157,7 +1096,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
Collection<String> coll = new HashSet<>();
|
||||
coll.add("coll1");
|
||||
accessor.setPropertyValue("collection", coll.toArray());
|
||||
List<String> set = new LinkedList<>();
|
||||
List<String> set = new ArrayList<>();
|
||||
set.add("set1");
|
||||
accessor.setPropertyValue("set", set.toArray());
|
||||
List<String> sortedSet = new ArrayList<>();
|
||||
@@ -1184,7 +1123,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
Collection<Integer> coll = new HashSet<>();
|
||||
coll.add(0);
|
||||
accessor.setPropertyValue("collection", new int[] {0});
|
||||
List<Integer> set = new LinkedList<>();
|
||||
List<Integer> set = new ArrayList<>();
|
||||
set.add(1);
|
||||
accessor.setPropertyValue("set", new int[] {1});
|
||||
List<Integer> sortedSet = new ArrayList<>();
|
||||
@@ -1211,7 +1150,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
Collection<Integer> coll = new HashSet<>();
|
||||
coll.add(0);
|
||||
accessor.setPropertyValue("collection", 0);
|
||||
List<Integer> set = new LinkedList<>();
|
||||
List<Integer> set = new ArrayList<>();
|
||||
set.add(1);
|
||||
accessor.setPropertyValue("set", 1);
|
||||
List<Integer> sortedSet = new ArrayList<>();
|
||||
@@ -1235,7 +1174,7 @@ public abstract class AbstractPropertyAccessorTests {
|
||||
public void setCollectionPropertyWithStringValue() {
|
||||
IndexedTestBean target = new IndexedTestBean();
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
List<String> set = new LinkedList<>();
|
||||
List<String> set = new ArrayList<>();
|
||||
set.add("set1");
|
||||
accessor.setPropertyValue("set", "set1");
|
||||
List<String> sortedSet = new ArrayList<>();
|
||||
|
||||
+13
-14
@@ -23,7 +23,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -197,8 +196,8 @@ public class BeanWrapperGenericsTests {
|
||||
@Test
|
||||
public void testGenericListOfLists() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<List<Integer>> list = new LinkedList<>();
|
||||
list.add(new LinkedList<>());
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
list.add(new ArrayList<>());
|
||||
gb.setListOfLists(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("listOfLists[0][0]", 5);
|
||||
@@ -209,8 +208,8 @@ public class BeanWrapperGenericsTests {
|
||||
@Test
|
||||
public void testGenericListOfListsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<List<Integer>> list = new LinkedList<>();
|
||||
list.add(new LinkedList<>());
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
list.add(new ArrayList<>());
|
||||
gb.setListOfLists(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("listOfLists[0][0]", "5");
|
||||
@@ -246,7 +245,7 @@ public class BeanWrapperGenericsTests {
|
||||
@Test
|
||||
public void testGenericListOfMaps() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<Map<Integer, Long>> list = new LinkedList<>();
|
||||
List<Map<Integer, Long>> list = new ArrayList<>();
|
||||
list.add(new HashMap<>());
|
||||
gb.setListOfMaps(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
@@ -258,7 +257,7 @@ public class BeanWrapperGenericsTests {
|
||||
@Test
|
||||
public void testGenericListOfMapsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<Map<Integer, Long>> list = new LinkedList<>();
|
||||
List<Map<Integer, Long>> list = new ArrayList<>();
|
||||
list.add(new HashMap<>());
|
||||
gb.setListOfMaps(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
@@ -295,7 +294,7 @@ public class BeanWrapperGenericsTests {
|
||||
public void testGenericMapOfLists() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
map.put(1, new LinkedList<>());
|
||||
map.put(1, new ArrayList<>());
|
||||
gb.setMapOfLists(map);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("mapOfLists[1][0]", 5);
|
||||
@@ -307,7 +306,7 @@ public class BeanWrapperGenericsTests {
|
||||
public void testGenericMapOfListsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
map.put(1, new LinkedList<>());
|
||||
map.put(1, new ArrayList<>());
|
||||
gb.setMapOfLists(map);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("mapOfLists[1][0]", "5");
|
||||
@@ -347,7 +346,7 @@ public class BeanWrapperGenericsTests {
|
||||
|
||||
@Test
|
||||
public void testGenericTypeNestingListOfMapOfInteger() throws Exception {
|
||||
List<Map<String, String>> list = new LinkedList<>();
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("testKey", "5");
|
||||
list.add(map);
|
||||
@@ -381,9 +380,9 @@ public class BeanWrapperGenericsTests {
|
||||
@Test
|
||||
public void testComplexGenericMap() {
|
||||
Map<List<String>, List<String>> inputMap = new HashMap<>();
|
||||
List<String> inputKey = new LinkedList<>();
|
||||
List<String> inputKey = new ArrayList<>();
|
||||
inputKey.add("1");
|
||||
List<String> inputValue = new LinkedList<>();
|
||||
List<String> inputValue = new ArrayList<>();
|
||||
inputValue.add("10");
|
||||
inputMap.put(inputKey, inputValue);
|
||||
|
||||
@@ -414,7 +413,7 @@ public class BeanWrapperGenericsTests {
|
||||
|
||||
@Test
|
||||
public void testComplexGenericIndexedMapEntry() {
|
||||
List<String> inputValue = new LinkedList<>();
|
||||
List<String> inputValue = new ArrayList<>();
|
||||
inputValue.add("10");
|
||||
|
||||
ComplexMapHolder holder = new ComplexMapHolder();
|
||||
@@ -440,7 +439,7 @@ public class BeanWrapperGenericsTests {
|
||||
|
||||
@Test
|
||||
public void testComplexDerivedIndexedMapEntry() {
|
||||
List<String> inputValue = new LinkedList<>();
|
||||
List<String> inputValue = new ArrayList<>();
|
||||
inputValue.add("10");
|
||||
|
||||
ComplexMapHolder holder = new ComplexMapHolder();
|
||||
|
||||
+16
-11
@@ -63,9 +63,8 @@ public class BeanFactoryUtilsTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
public void setup() {
|
||||
// Interesting hierarchical factory to test counts.
|
||||
// Slow to read so we cache it.
|
||||
|
||||
DefaultListableBeanFactory grandParent = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(grandParent).loadBeanDefinitions(ROOT_CONTEXT);
|
||||
@@ -93,7 +92,7 @@ public class BeanFactoryUtilsTests {
|
||||
* Check that override doesn't count as two separate beans.
|
||||
*/
|
||||
@Test
|
||||
public void testHierarchicalCountBeansWithOverride() throws Exception {
|
||||
public void testHierarchicalCountBeansWithOverride() {
|
||||
// Leaf count
|
||||
assertThat(this.listableBeanFactory.getBeanDefinitionCount() == 1).isTrue();
|
||||
// Count minus duplicate
|
||||
@@ -101,14 +100,14 @@ public class BeanFactoryUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesWithNoMatch() throws Exception {
|
||||
public void testHierarchicalNamesWithNoMatch() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, NoOp.class));
|
||||
assertThat(names.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesWithMatchOnlyInRoot() throws Exception {
|
||||
public void testHierarchicalNamesWithMatchOnlyInRoot() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, IndexedTestBean.class));
|
||||
assertThat(names.size()).isEqualTo(1);
|
||||
@@ -118,7 +117,7 @@ public class BeanFactoryUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanNamesForTypeWithOverride() throws Exception {
|
||||
public void testGetBeanNamesForTypeWithOverride() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class));
|
||||
// includes 2 TestBeans from FactoryBeans (DummyFactory definitions)
|
||||
@@ -236,7 +235,7 @@ public class BeanFactoryUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalResolutionWithOverride() throws Exception {
|
||||
public void testHierarchicalResolutionWithOverride() {
|
||||
Object test3 = this.listableBeanFactory.getBean("test3");
|
||||
Object test = this.listableBeanFactory.getBean("test");
|
||||
|
||||
@@ -276,14 +275,14 @@ public class BeanFactoryUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesForAnnotationWithNoMatch() throws Exception {
|
||||
public void testHierarchicalNamesForAnnotationWithNoMatch() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, Override.class));
|
||||
assertThat(names.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesForAnnotationWithMatchOnlyInRoot() throws Exception {
|
||||
public void testHierarchicalNamesForAnnotationWithMatchOnlyInRoot() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, TestAnnotation.class));
|
||||
assertThat(names.size()).isEqualTo(1);
|
||||
@@ -293,7 +292,7 @@ public class BeanFactoryUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanNamesForAnnotationWithOverride() throws Exception {
|
||||
public void testGetBeanNamesForAnnotationWithOverride() {
|
||||
AnnotatedBean annotatedBean = new AnnotatedBean();
|
||||
this.listableBeanFactory.registerSingleton("anotherAnnotatedBean", annotatedBean);
|
||||
List<String> names = Arrays.asList(
|
||||
@@ -433,6 +432,7 @@ public class BeanFactoryUtilsTests {
|
||||
String basePackage() default "";
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ControllerAdvice
|
||||
@interface RestControllerAdvice {
|
||||
@@ -444,18 +444,23 @@ public class BeanFactoryUtilsTests {
|
||||
String basePackage() default "";
|
||||
}
|
||||
|
||||
|
||||
@ControllerAdvice("com.example")
|
||||
static class ControllerAdviceClass {
|
||||
}
|
||||
|
||||
|
||||
@RestControllerAdvice("com.example")
|
||||
static class RestControllerAdviceClass {
|
||||
}
|
||||
|
||||
|
||||
static class TestBeanSmartFactoryBean implements SmartFactoryBean<TestBean> {
|
||||
|
||||
private final TestBean testBean = new TestBean("enigma", 42);
|
||||
|
||||
private final boolean singleton;
|
||||
|
||||
private final boolean prototype;
|
||||
|
||||
TestBeanSmartFactoryBean(boolean singleton, boolean prototype) {
|
||||
@@ -478,7 +483,7 @@ public class BeanFactoryUtilsTests {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
public TestBean getObject() throws Exception {
|
||||
public TestBean getObject() {
|
||||
// We don't really care if the actual instance is a singleton or prototype
|
||||
// for the tests that use this factory.
|
||||
return this.testBean;
|
||||
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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
|
||||
*
|
||||
* https://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.beans.factory;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.core.testfixture.EnabledForTestGroups;
|
||||
import org.springframework.core.testfixture.TestGroup;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifiedResource;
|
||||
|
||||
/**
|
||||
* @author Guillaume Poirier
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 10.03.2004
|
||||
*/
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
public class ConcurrentBeanFactoryTests {
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
|
||||
|
||||
private static final Date DATE_1, DATE_2;
|
||||
|
||||
static {
|
||||
try {
|
||||
DATE_1 = DATE_FORMAT.parse("2004/08/08");
|
||||
DATE_2 = DATE_FORMAT.parse("2000/02/02");
|
||||
}
|
||||
catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ConcurrentBeanFactoryTests.class);
|
||||
|
||||
private BeanFactory factory;
|
||||
|
||||
private final Set<TestRun> set = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
private Throwable ex;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(
|
||||
qualifiedResource(ConcurrentBeanFactoryTests.class, "context.xml"));
|
||||
|
||||
factory.addPropertyEditorRegistrar(
|
||||
registry -> registry.registerCustomEditor(Date.class,
|
||||
new CustomDateEditor((DateFormat) DATE_FORMAT.clone(), false)));
|
||||
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSingleThread() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
performTest();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcurrent() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
TestRun run = new TestRun();
|
||||
run.setDaemon(true);
|
||||
set.add(run);
|
||||
}
|
||||
for (Iterator<TestRun> it = new HashSet<>(set).iterator(); it.hasNext();) {
|
||||
TestRun run = it.next();
|
||||
run.start();
|
||||
}
|
||||
logger.info("Thread creation over, " + set.size() + " still active.");
|
||||
synchronized (set) {
|
||||
while (!set.isEmpty() && ex == null) {
|
||||
try {
|
||||
set.wait();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
logger.info(e.toString());
|
||||
}
|
||||
logger.info(set.size() + " threads still active.");
|
||||
}
|
||||
}
|
||||
if (ex != null) {
|
||||
throw new AssertionError("Unexpected exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void performTest() {
|
||||
ConcurrentBean b1 = (ConcurrentBean) factory.getBean("bean1");
|
||||
ConcurrentBean b2 = (ConcurrentBean) factory.getBean("bean2");
|
||||
|
||||
assertThat(b1.getDate()).isEqualTo(DATE_1);
|
||||
assertThat(b2.getDate()).isEqualTo(DATE_2);
|
||||
}
|
||||
|
||||
|
||||
private class TestRun extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
performTest();
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
ex = e;
|
||||
}
|
||||
finally {
|
||||
synchronized (set) {
|
||||
set.remove(this);
|
||||
set.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ConcurrentBean {
|
||||
|
||||
private Date date;
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
-243
@@ -43,10 +43,7 @@ import java.util.stream.IntStream;
|
||||
import javax.annotation.Priority;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
@@ -80,7 +77,6 @@ import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.beans.testfixture.beans.DependenciesBean;
|
||||
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
import org.springframework.beans.testfixture.beans.LifecycleBean;
|
||||
import org.springframework.beans.testfixture.beans.NestedTestBean;
|
||||
import org.springframework.beans.testfixture.beans.SideEffectBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
@@ -93,13 +89,9 @@ import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.testfixture.Assume;
|
||||
import org.springframework.core.testfixture.EnabledForTestGroups;
|
||||
import org.springframework.core.testfixture.TestGroup;
|
||||
import org.springframework.core.testfixture.io.SerializationTestUtils;
|
||||
import org.springframework.core.testfixture.security.TestPrincipal;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -127,8 +119,6 @@ import static org.mockito.Mockito.verify;
|
||||
*/
|
||||
class DefaultListableBeanFactoryTests {
|
||||
|
||||
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
|
||||
|
||||
private DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
@@ -795,12 +785,13 @@ class DefaultListableBeanFactoryTests {
|
||||
factory.registerBeanDefinition("child", childDefinition);
|
||||
factory.registerAlias("parent", "alias");
|
||||
|
||||
TestBean child = (TestBean) factory.getBean("child");
|
||||
TestBean child = factory.getBean("child", TestBean.class);
|
||||
assertThat(child.getName()).isEqualTo(EXPECTED_NAME);
|
||||
assertThat(child.getAge()).isEqualTo(EXPECTED_AGE);
|
||||
Object mergedBeanDefinition2 = factory.getMergedBeanDefinition("child");
|
||||
BeanDefinition mergedBeanDefinition1 = factory.getMergedBeanDefinition("child");
|
||||
BeanDefinition mergedBeanDefinition2 = factory.getMergedBeanDefinition("child");
|
||||
|
||||
assertThat(mergedBeanDefinition2).as("Use cached merged bean definition").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(mergedBeanDefinition1).as("Use cached merged bean definition").isSameAs(mergedBeanDefinition2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1848,8 +1839,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(factoryBean).as("The FactoryBean should have been registered.").isNotNull();
|
||||
FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
|
||||
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
Object mergedBeanDefinition2 = bean.getFactoryBean();
|
||||
assertThat(mergedBeanDefinition2).as("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(bean.getFactoryBean()).as("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.").isEqualTo(factoryBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2352,163 +2342,6 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(tb2.getBeanName()).isEqualTo("myBeanName");
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
lbf.getBean("test");
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 3000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationWithDependencyCheckIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(LifecycleBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.addBeanPostProcessor(new LifecycleBean.PostProcessor());
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
lbf.getBean("test");
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 3000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationWithConstructorArgumentsIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue("juergen");
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue("99");
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb.getName()).isEqualTo("juergen");
|
||||
assertThat(tb.getAge()).isEqualTo(99);
|
||||
}
|
||||
sw.stop();
|
||||
assertThat(sw.getTotalTimeMillis() < 3000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationWithResolvedConstructorArgumentsIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("spouse"));
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
|
||||
lbf.freezeConfiguration();
|
||||
TestBean spouse = (TestBean) lbf.getBean("spouse");
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb.getSpouse()).isSameAs(spouse);
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationWithPropertiesIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.getPropertyValues().add("name", "juergen");
|
||||
rbd.getPropertyValues().add("age", "99");
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb.getName()).isEqualTo("juergen");
|
||||
assertThat(tb.getAge()).isEqualTo(99);
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void prototypeCreationWithResolvedPropertiesIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
|
||||
lbf.registerBeanDefinition("test", rbd);
|
||||
lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
|
||||
lbf.freezeConfiguration();
|
||||
TestBean spouse = (TestBean) lbf.getBean("spouse");
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("prototype");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb.getSpouse()).isSameAs(spouse);
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void singletonLookupByNameIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("singleton");
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
lbf.getBean("test");
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 1000).as("Singleton lookup took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void singletonLookupByTypeIsFastEnough() {
|
||||
Assume.notLogging(factoryLog);
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
lbf.freezeConfiguration();
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("singleton");
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
lbf.getBean(TestBean.class);
|
||||
}
|
||||
sw.stop();
|
||||
// System.out.println(sw.getTotalTimeMillis());
|
||||
assertThat(sw.getTotalTimeMillis() < 1000).as("Singleton lookup took too long: " + sw.getTotalTimeMillis()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanPostProcessorWithWrappedObjectAndDisposableBean() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(BeanWithDisposableBean.class);
|
||||
@@ -2555,8 +2388,7 @@ class DefaultListableBeanFactoryTests {
|
||||
BeanWithDestroyMethod.closeCount = 0;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
|
||||
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2570,8 +2402,7 @@ class DefaultListableBeanFactoryTests {
|
||||
BeanWithDestroyMethod.closeCount = 0;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
|
||||
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2586,8 +2417,7 @@ class DefaultListableBeanFactoryTests {
|
||||
BeanWithDestroyMethod.closeCount = 0;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
|
||||
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2709,14 +2539,15 @@ class DefaultListableBeanFactoryTests {
|
||||
factory.registerBeanDefinition("child", child);
|
||||
|
||||
AbstractBeanDefinition def = (AbstractBeanDefinition) factory.getBeanDefinition("child");
|
||||
Object mergedBeanDefinition2 = def.getScope();
|
||||
assertThat(mergedBeanDefinition2).as("Child 'scope' not overriding parent scope (it must).").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(def.getScope()).as("Child 'scope' not overriding parent scope (it must).").isEqualTo(theChildScope);
|
||||
}
|
||||
|
||||
@Test
|
||||
void scopeInheritanceForChildBeanDefinitions() {
|
||||
String theParentScope = "bonanza!";
|
||||
|
||||
RootBeanDefinition parent = new RootBeanDefinition();
|
||||
parent.setScope("bonanza!");
|
||||
parent.setScope(theParentScope);
|
||||
|
||||
AbstractBeanDefinition child = new ChildBeanDefinition("parent");
|
||||
child.setBeanClass(TestBean.class);
|
||||
@@ -2726,8 +2557,7 @@ class DefaultListableBeanFactoryTests {
|
||||
factory.registerBeanDefinition("child", child);
|
||||
|
||||
BeanDefinition def = factory.getMergedBeanDefinition("child");
|
||||
Object mergedBeanDefinition2 = def.getScope();
|
||||
assertThat(mergedBeanDefinition2).as("Child 'scope' not inherited").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(def.getScope()).as("Child 'scope' not inherited").isEqualTo(theParentScope);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2763,15 +2593,12 @@ class DefaultListableBeanFactoryTests {
|
||||
});
|
||||
lbf.preInstantiateSingletons();
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
Object mergedBeanDefinition2 = tb.getName();
|
||||
assertThat(mergedBeanDefinition2).as("Name was set on field by IAPP").isEqualTo(mergedBeanDefinition2);
|
||||
assertThat(tb.getName()).as("Name was set on field by IAPP").isEqualTo(nameSetOnField);
|
||||
if (!skipPropertyPopulation) {
|
||||
Object mergedBeanDefinition21 = tb.getAge();
|
||||
assertThat(mergedBeanDefinition21).as("Property value still set").isEqualTo(mergedBeanDefinition21);
|
||||
assertThat(tb.getAge()).as("Property value still set").isEqualTo(ageSetByPropertyValue);
|
||||
}
|
||||
else {
|
||||
Object mergedBeanDefinition21 = tb.getAge();
|
||||
assertThat(mergedBeanDefinition21).as("Property value was NOT set and still has default value").isEqualTo(mergedBeanDefinition21);
|
||||
assertThat(tb.getAge()).as("Property value was NOT set and still has default value").isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2844,55 +2671,6 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(holder.getNonPublicEnum()).isEqualTo(NonPublicEnum.VALUE_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that by-type bean lookup caching is working effectively by searching for a
|
||||
* bean of type B 10K times within a container having 1K additional beans of type A.
|
||||
* Prior to by-type caching, each bean lookup would traverse the entire container
|
||||
* (all 1001 beans), performing expensive assignability checks, etc. Now these
|
||||
* operations are necessary only once, providing a dramatic performance improvement.
|
||||
* On load-free modern hardware (e.g. an 8-core MPB), this method should complete well
|
||||
* under the 1000 ms timeout, usually ~= 300ms. With caching removed and on the same
|
||||
* hardware the method will take ~13000 ms. See SPR-6870.
|
||||
*/
|
||||
@Test
|
||||
@Timeout(1)
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void byTypeLookupIsFastEnough() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
lbf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
|
||||
}
|
||||
lbf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
|
||||
|
||||
lbf.freezeConfiguration();
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
lbf.getBean(B.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(1)
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void registrationOfManyBeanDefinitionsIsFastEnough() {
|
||||
lbf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
|
||||
// lbf.getBean("b");
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
lbf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(1)
|
||||
@EnabledForTestGroups(TestGroup.PERFORMANCE)
|
||||
void registrationOfManySingletonsIsFastEnough() {
|
||||
lbf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
|
||||
// lbf.getBean("b");
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
lbf.registerSingleton("a" + i, new A());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private int registerBeanDefinitions(Properties p) {
|
||||
@@ -2905,11 +2683,6 @@ class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
|
||||
static class A { }
|
||||
|
||||
static class B { }
|
||||
|
||||
|
||||
public static class NoDependencies {
|
||||
|
||||
private NoDependencies() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -286,7 +286,7 @@ public class FactoryBeanTests {
|
||||
}
|
||||
AtomicInteger c = count.get(beanName);
|
||||
if (c == null) {
|
||||
c = new AtomicInteger(0);
|
||||
c = new AtomicInteger();
|
||||
count.put(beanName, c);
|
||||
}
|
||||
c.incrementAndGet();
|
||||
|
||||
+4
-4
@@ -24,13 +24,13 @@ import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -2709,7 +2709,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class SelfInjectionCollectionBean extends LinkedList<SelfInjectionCollectionBean> {
|
||||
public static class SelfInjectionCollectionBean extends ArrayList<SelfInjectionCollectionBean> {
|
||||
|
||||
@Autowired
|
||||
public SelfInjectionCollectionBean reference;
|
||||
@@ -2833,7 +2833,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
public List<TestBean> iterateTestBeans() {
|
||||
List<TestBean> resolved = new LinkedList<>();
|
||||
List<TestBean> resolved = new ArrayList<>();
|
||||
for (TestBean tb : this.testBeanProvider) {
|
||||
resolved.add(tb);
|
||||
}
|
||||
@@ -2841,7 +2841,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
public List<TestBean> forEachTestBeans() {
|
||||
List<TestBean> resolved = new LinkedList<>();
|
||||
List<TestBean> resolved = new ArrayList<>();
|
||||
this.testBeanProvider.forEach(resolved::add);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
+15
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -108,10 +108,23 @@ public class LookupAnnotationTests {
|
||||
assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean);
|
||||
}
|
||||
|
||||
@Test // gh-25806
|
||||
public void testWithNullBean() {
|
||||
RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class, () -> null);
|
||||
tbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
beanFactory.registerBeanDefinition("testBean", tbd);
|
||||
|
||||
AbstractBean bean = beanFactory.getBean("beanConsumer", BeanConsumer.class).abstractBean;
|
||||
assertThat(bean).isNotNull();
|
||||
Object expected = bean.get();
|
||||
assertThat(expected).isNull();
|
||||
assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean);
|
||||
}
|
||||
|
||||
|
||||
public static abstract class AbstractBean {
|
||||
|
||||
@Lookup
|
||||
@Lookup("testBean")
|
||||
public abstract TestBean get();
|
||||
|
||||
@Lookup
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -47,7 +47,7 @@ public class SimpleScopeTests {
|
||||
beanFactory = new DefaultListableBeanFactory();
|
||||
Scope scope = new NoOpScope() {
|
||||
private int index;
|
||||
private List<TestBean> objects = new LinkedList<>(); {
|
||||
private List<TestBean> objects = new ArrayList<>(); {
|
||||
objects.add(new TestBean());
|
||||
objects.add(new TestBean());
|
||||
}
|
||||
|
||||
+20
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +24,6 @@ import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.DuplicateKeyException;
|
||||
import org.yaml.snakeyaml.scanner.ScannerException;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
|
||||
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
|
||||
import org.springframework.beans.factory.config.YamlProcessor.ResolutionMethod;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
@@ -39,10 +38,10 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Dave Syer
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class YamlPropertiesFactoryBeanTests {
|
||||
class YamlPropertiesFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void loadResource() {
|
||||
void loadResource() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
|
||||
Properties properties = factory.getObject();
|
||||
@@ -51,7 +50,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void badResource() {
|
||||
void badResource() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("foo: bar\ncd\nspam:\n foo: baz".getBytes()));
|
||||
assertThatExceptionOfType(ScannerException.class)
|
||||
@@ -60,7 +59,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourcesWithOverride() {
|
||||
void loadResourcesWithOverride() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(
|
||||
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()),
|
||||
@@ -72,7 +71,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourcesWithInternalOverride() {
|
||||
void loadResourcesWithInternalOverride() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"foo: bar\nspam:\n foo: baz\nfoo: bucket".getBytes()));
|
||||
@@ -80,7 +79,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourcesWithNestedInternalOverride() {
|
||||
void loadResourcesWithNestedInternalOverride() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"foo:\n bar: spam\n foo: baz\nbreak: it\nfoo: bucket".getBytes()));
|
||||
@@ -88,7 +87,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWithMultipleDocuments() {
|
||||
void loadResourceWithMultipleDocuments() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"foo: bar\nspam: baz\n---\nfoo: bag".getBytes()));
|
||||
@@ -98,7 +97,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWithSelectedDocuments() {
|
||||
void loadResourceWithSelectedDocuments() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"foo: bar\nspam: baz\n---\nfoo: bag\nspam: bad".getBytes()));
|
||||
@@ -110,7 +109,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWithDefaultMatch() {
|
||||
void loadResourceWithDefaultMatch() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setMatchDefault(true);
|
||||
factory.setResources(new ByteArrayResource(
|
||||
@@ -129,20 +128,17 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWithoutDefaultMatch() {
|
||||
void loadResourceWithoutDefaultMatch() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setMatchDefault(false);
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"one: two\n---\nfoo: bar\nspam: baz\n---\nfoo: bag\nspam: bad".getBytes()));
|
||||
factory.setDocumentMatchers(new DocumentMatcher() {
|
||||
@Override
|
||||
public MatchStatus matches(Properties properties) {
|
||||
factory.setDocumentMatchers(properties -> {
|
||||
if (!properties.containsKey("foo")) {
|
||||
return MatchStatus.ABSTAIN;
|
||||
}
|
||||
return ("bag".equals(properties.getProperty("foo")) ?
|
||||
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
|
||||
}
|
||||
});
|
||||
Properties properties = factory.getObject();
|
||||
assertThat(properties.getProperty("foo")).isEqualTo("bag");
|
||||
@@ -151,7 +147,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWithDefaultMatchSkippingMissedMatch() {
|
||||
void loadResourceWithDefaultMatchSkippingMissedMatch() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setMatchDefault(true);
|
||||
factory.setResources(new ByteArrayResource(
|
||||
@@ -170,7 +166,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadNonExistentResource() {
|
||||
void loadNonExistentResource() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResolutionMethod(ResolutionMethod.OVERRIDE_AND_IGNORE);
|
||||
factory.setResources(new ClassPathResource("no-such-file.yml"));
|
||||
@@ -179,7 +175,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadNull() {
|
||||
void loadNull() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("foo: bar\nspam:".getBytes()));
|
||||
Properties properties = factory.getObject();
|
||||
@@ -188,7 +184,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadEmptyArrayValue() {
|
||||
void loadEmptyArrayValue() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("a: alpha\ntest: []".getBytes()));
|
||||
Properties properties = factory.getObject();
|
||||
@@ -197,7 +193,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadArrayOfString() {
|
||||
void loadArrayOfString() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("foo:\n- bar\n- baz".getBytes()));
|
||||
Properties properties = factory.getObject();
|
||||
@@ -207,7 +203,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadArrayOfInteger() {
|
||||
void loadArrayOfInteger() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource("foo:\n- 1\n- 2".getBytes()));
|
||||
Properties properties = factory.getObject();
|
||||
@@ -217,7 +213,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadArrayOfObject() {
|
||||
void loadArrayOfObject() {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(new ByteArrayResource(
|
||||
"foo:\n- bar:\n spam: crap\n- baz\n- one: two\n three: four".getBytes()
|
||||
@@ -232,7 +228,7 @@ public class YamlPropertiesFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void yaml() {
|
||||
void yaml() {
|
||||
Yaml yaml = new Yaml();
|
||||
Map<String, ?> map = yaml.loadAs("foo: bar\nspam:\n foo: baz", Map.class);
|
||||
assertThat(map.get("foo")).isEqualTo("bar");
|
||||
|
||||
+1
-2
@@ -26,7 +26,6 @@ import java.util.AbstractCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -960,7 +959,7 @@ public class BeanFactoryGenericsTests {
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class NamedUrlList extends LinkedList<URL> {
|
||||
public static class NamedUrlList extends ArrayList<URL> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -126,7 +126,7 @@ public class DefinitionMetadataEqualsHashCodeTests {
|
||||
assertThat(equal.hashCode()).as("Hash code for equal instances should match").isEqualTo(master.hashCode());
|
||||
|
||||
assertThat(notEqual).as("Should not be equal").isNotEqualTo(master);
|
||||
assertThat(notEqual.hashCode()).as("Hash code for non-equal instances should not match").isNotEqualTo((long) master.hashCode());
|
||||
assertThat(notEqual.hashCode()).as("Hash code for non-equal instances should not match").isNotEqualTo(master.hashCode());
|
||||
|
||||
assertThat(subclass).as("Subclass should be equal").isEqualTo(master);
|
||||
assertThat(subclass.hashCode()).as("Hash code for subclass should match").isEqualTo(master.hashCode());
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,13 +35,13 @@ import org.springframework.beans.factory.parsing.ReaderEventListener;
|
||||
*/
|
||||
public class CollectingReaderEventListener implements ReaderEventListener {
|
||||
|
||||
private final List<DefaultsDefinition> defaults = new LinkedList<>();
|
||||
private final List<DefaultsDefinition> defaults = new ArrayList<>();
|
||||
|
||||
private final Map<String, ComponentDefinition> componentDefinitions = new LinkedHashMap<>(8);
|
||||
|
||||
private final Map<String, List<AliasDefinition>> aliasMap = new LinkedHashMap<>(8);
|
||||
|
||||
private final List<ImportDefinition> imports = new LinkedList<>();
|
||||
private final List<ImportDefinition> imports = new ArrayList<>();
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -77,7 +76,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
|
||||
private Float myFloat = Float.valueOf(0.0f);
|
||||
|
||||
private Collection<? super Object> friends = new LinkedList<>();
|
||||
private Collection<? super Object> friends = new ArrayList<>();
|
||||
|
||||
private Set<?> someSet = new HashSet<>();
|
||||
|
||||
|
||||
-1
@@ -101,7 +101,6 @@ class KeyGeneratorAdapter implements KeyGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object doGenerate(KeyGenerator keyGenerator, CacheKeyInvocationContext<?> context) {
|
||||
List<Object> parameters = new ArrayList<>();
|
||||
for (CacheInvocationParameter param : context.getKeyParameters()) {
|
||||
|
||||
+39
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -159,8 +159,6 @@ public class MimeMessageHelper {
|
||||
|
||||
private static final String HEADER_PRIORITY = "X-Priority";
|
||||
|
||||
private static final String HEADER_CONTENT_ID = "Content-ID";
|
||||
|
||||
|
||||
private final MimeMessage mimeMessage;
|
||||
|
||||
@@ -175,6 +173,8 @@ public class MimeMessageHelper {
|
||||
|
||||
private FileTypeMap fileTypeMap;
|
||||
|
||||
private boolean encodeFilenames = false;
|
||||
|
||||
private boolean validateAddresses = false;
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ public class MimeMessageHelper {
|
||||
* Set the Java Activation Framework {@code FileTypeMap} to use
|
||||
* for determining the content type of inline content and attachments
|
||||
* that get added to the message.
|
||||
* <p>Default is the {@code FileTypeMap} that the underlying
|
||||
* <p>The default is the {@code FileTypeMap} that the underlying
|
||||
* MimeMessage carries, if any, or the Activation Framework's default
|
||||
* {@code FileTypeMap} instance else.
|
||||
* @see #addInline
|
||||
@@ -480,18 +480,42 @@ public class MimeMessageHelper {
|
||||
|
||||
/**
|
||||
* Return the {@code FileTypeMap} used by this MimeMessageHelper.
|
||||
* @see #setFileTypeMap
|
||||
*/
|
||||
public FileTypeMap getFileTypeMap() {
|
||||
return this.fileTypeMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to encode attachment filenames passed to this helper's
|
||||
* {@code #addAttachment} methods.
|
||||
* <p>The default is {@code false} for standard MIME behavior; turn this to
|
||||
* {@code true} for compatibility with older email clients. On a related note,
|
||||
* check out JavaMail's {@code mail.mime.encodefilename} system property.
|
||||
* <p><b>NOTE:</b> The default changed to {@code false} in 5.3, in favor of
|
||||
* JavaMail's standard {@code mail.mime.encodefilename} system property.
|
||||
* @since 5.2.9
|
||||
* @see #addAttachment(String, DataSource)
|
||||
* @see MimeBodyPart#setFileName(String)
|
||||
*/
|
||||
public void setEncodeFilenames(boolean encodeFilenames) {
|
||||
this.encodeFilenames = encodeFilenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to encode attachment filenames passed to this helper's
|
||||
* {@code #addAttachment} methods.
|
||||
* @since 5.2.9
|
||||
* @see #setEncodeFilenames
|
||||
*/
|
||||
public boolean isEncodeFilenames() {
|
||||
return this.encodeFilenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to validate all addresses which get passed to this helper.
|
||||
* Default is "false".
|
||||
* <p>Note that this is by default just available for JavaMail >= 1.3.
|
||||
* You can override the default {@code validateAddress method} for
|
||||
* validation on older JavaMail versions (or for custom validation).
|
||||
* <p>The default is {@code false}.
|
||||
* @see #validateAddress
|
||||
*/
|
||||
public void setValidateAddresses(boolean validateAddresses) {
|
||||
@@ -500,6 +524,7 @@ public class MimeMessageHelper {
|
||||
|
||||
/**
|
||||
* Return whether this helper will validate all addresses passed to it.
|
||||
* @see #setValidateAddresses
|
||||
*/
|
||||
public boolean isValidateAddresses() {
|
||||
return this.validateAddresses;
|
||||
@@ -508,10 +533,8 @@ public class MimeMessageHelper {
|
||||
/**
|
||||
* Validate the given mail address.
|
||||
* Called by all of MimeMessageHelper's address setters and adders.
|
||||
* <p>Default implementation invokes {@code InternetAddress.validate()},
|
||||
* <p>The default implementation invokes {@link InternetAddress#validate()},
|
||||
* provided that address validation is activated for the helper instance.
|
||||
* <p>Note that this method will just work on JavaMail >= 1.3. You can override
|
||||
* it for validation on older JavaMail versions or for custom validation.
|
||||
* @param address the address to validate
|
||||
* @throws AddressException if validation failed
|
||||
* @see #isValidateAddresses()
|
||||
@@ -525,7 +548,8 @@ public class MimeMessageHelper {
|
||||
|
||||
/**
|
||||
* Validate all given mail addresses.
|
||||
* Default implementation simply delegates to validateAddress for each address.
|
||||
* <p>The default implementation simply delegates to {@link #validateAddress}
|
||||
* for each address.
|
||||
* @param addresses the addresses to validate
|
||||
* @throws AddressException if validation failed
|
||||
* @see #validateAddress(InternetAddress)
|
||||
@@ -885,9 +909,7 @@ public class MimeMessageHelper {
|
||||
Assert.notNull(dataSource, "DataSource must not be null");
|
||||
MimeBodyPart mimeBodyPart = new MimeBodyPart();
|
||||
mimeBodyPart.setDisposition(MimeBodyPart.INLINE);
|
||||
// We're using setHeader here to remain compatible with JavaMail 1.2,
|
||||
// rather than JavaMail 1.3's setContentID.
|
||||
mimeBodyPart.setHeader(HEADER_CONTENT_ID, "<" + contentId + ">");
|
||||
mimeBodyPart.setContentID("<" + contentId + ">");
|
||||
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
|
||||
getMimeMultipart().addBodyPart(mimeBodyPart);
|
||||
}
|
||||
@@ -997,7 +1019,8 @@ public class MimeMessageHelper {
|
||||
try {
|
||||
MimeBodyPart mimeBodyPart = new MimeBodyPart();
|
||||
mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
|
||||
mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename));
|
||||
mimeBodyPart.setFileName(isEncodeFilenames() ?
|
||||
MimeUtility.encodeText(attachmentFilename) : attachmentFilename);
|
||||
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
|
||||
getRootMimeMultipart().addBodyPart(mimeBodyPart);
|
||||
}
|
||||
|
||||
+14
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +16,7 @@
|
||||
|
||||
package org.springframework.scheduling.commonj;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
@@ -62,7 +62,8 @@ public class TimerManagerFactoryBean extends TimerManagerAccessor
|
||||
@Nullable
|
||||
private ScheduledTimerListener[] scheduledTimerListeners;
|
||||
|
||||
private final List<Timer> timers = new LinkedList<>();
|
||||
@Nullable
|
||||
private List<Timer> timers;
|
||||
|
||||
|
||||
/**
|
||||
@@ -87,6 +88,7 @@ public class TimerManagerFactoryBean extends TimerManagerAccessor
|
||||
super.afterPropertiesSet();
|
||||
|
||||
if (this.scheduledTimerListeners != null) {
|
||||
this.timers = new ArrayList<>(this.scheduledTimerListeners.length);
|
||||
TimerManager timerManager = obtainTimerManager();
|
||||
for (ScheduledTimerListener scheduledTask : this.scheduledTimerListeners) {
|
||||
Timer timer;
|
||||
@@ -144,15 +146,17 @@ public class TimerManagerFactoryBean extends TimerManagerAccessor
|
||||
@Override
|
||||
public void destroy() {
|
||||
// Cancel all registered timers.
|
||||
for (Timer timer : this.timers) {
|
||||
try {
|
||||
timer.cancel();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Could not cancel CommonJ Timer", ex);
|
||||
if (this.timers != null) {
|
||||
for (Timer timer : this.timers) {
|
||||
try {
|
||||
timer.cancel();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Could not cancel CommonJ Timer", ex);
|
||||
}
|
||||
}
|
||||
this.timers.clear();
|
||||
}
|
||||
this.timers.clear();
|
||||
|
||||
// Stop the TimerManager itself.
|
||||
super.destroy();
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +17,7 @@
|
||||
package org.springframework.scheduling.quartz;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
@@ -147,7 +148,8 @@ public class LocalDataSourceJobStore extends JobStoreCMT {
|
||||
|
||||
// No, if HSQL is the platform, we really don't want to use locks...
|
||||
try {
|
||||
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName");
|
||||
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource,
|
||||
DatabaseMetaData::getDatabaseProductName);
|
||||
productName = JdbcUtils.commonDatabaseName(productName);
|
||||
if (productName != null && productName.toLowerCase().contains("hsql")) {
|
||||
setUseDBLocks(false);
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,7 +18,6 @@ package org.springframework.scheduling.quartz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -228,7 +227,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
|
||||
}
|
||||
else {
|
||||
// Create empty list for easier checks when registering triggers.
|
||||
this.jobDetails = new LinkedList<>();
|
||||
this.jobDetails = new ArrayList<>();
|
||||
}
|
||||
|
||||
// Register Calendars.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -46,7 +46,7 @@ public abstract class FreeMarkerTemplateUtils {
|
||||
public static String processTemplateIntoString(Template template, Object model)
|
||||
throws IOException, TemplateException {
|
||||
|
||||
StringWriter result = new StringWriter();
|
||||
StringWriter result = new StringWriter(1024);
|
||||
template.process(model, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
+9
-9
@@ -46,7 +46,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
@@ -96,7 +96,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithTaskExecutor() throws Exception {
|
||||
CountingTaskExecutor taskExecutor = new CountingTaskExecutor();
|
||||
DummyJob.count = 0;
|
||||
@@ -137,7 +137,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithQuartzJobBean() throws Exception {
|
||||
DummyJob.param = 0;
|
||||
DummyJob.count = 0;
|
||||
@@ -170,7 +170,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithSpringBeanJobFactory() throws Exception {
|
||||
DummyJob.param = 0;
|
||||
DummyJob.count = 0;
|
||||
@@ -205,7 +205,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception {
|
||||
DummyJob.param = 0;
|
||||
DummyJob.count = 0;
|
||||
@@ -241,7 +241,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception {
|
||||
DummyJobBean.param = 0;
|
||||
DummyJobBean.count = 0;
|
||||
@@ -275,7 +275,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception {
|
||||
DummyJob.param = 0;
|
||||
DummyJob.count = 0;
|
||||
@@ -316,7 +316,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception {
|
||||
Thread.sleep(3000);
|
||||
try (ClassPathXmlApplicationContext ctx = context("multipleAnonymousMethodInvokingJobDetailFB.xml")) {
|
||||
@@ -331,7 +331,7 @@ public class QuartzSupportTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(PERFORMANCE)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
public void schedulerAccessorBean() throws Exception {
|
||||
Thread.sleep(3000);
|
||||
try (ClassPathXmlApplicationContext ctx = context("schedulerAccessorBean.xml")) {
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -28,7 +28,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -406,7 +405,7 @@ public class SpringValidatorAdapterTests {
|
||||
private Set<Child> childSet = new LinkedHashSet<>();
|
||||
|
||||
@Valid
|
||||
private List<Child> childList = new LinkedList<>();
|
||||
private List<Child> childList = new ArrayList<>();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -20,10 +20,10 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -295,7 +295,7 @@ public class ValidatorFactoryTests {
|
||||
private ValidAddress address = new ValidAddress();
|
||||
|
||||
@Valid
|
||||
private List<ValidAddress> addressList = new LinkedList<>();
|
||||
private List<ValidAddress> addressList = new ArrayList<>();
|
||||
|
||||
@Valid
|
||||
private Set<ValidAddress> addressSet = new LinkedHashSet<>();
|
||||
@@ -457,7 +457,7 @@ public class ValidatorFactoryTests {
|
||||
public static class ListContainer {
|
||||
|
||||
@NotXList
|
||||
private List<String> list = new LinkedList<>();
|
||||
private List<String> list = new ArrayList<>();
|
||||
|
||||
public void addString(String value) {
|
||||
list.add(value);
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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
|
||||
*
|
||||
* https://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.context.annotation;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* Benchmark for bean annotation processing with various annotations.
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
public class AnnotationProcessorBenchmark {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class BenchmarkState {
|
||||
|
||||
public GenericApplicationContext context;
|
||||
|
||||
@Param({"ResourceAnnotatedTestBean", "AutowiredAnnotatedTestBean"})
|
||||
public String testBeanClass;
|
||||
|
||||
@Param({"true", "false"})
|
||||
public boolean overridden;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
RootBeanDefinition rbd;
|
||||
this.context = new GenericApplicationContext();
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.context);
|
||||
this.context.refresh();
|
||||
if (this.testBeanClass.equals("ResourceAnnotatedTestBean")) {
|
||||
rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class);
|
||||
}
|
||||
else {
|
||||
rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class);
|
||||
}
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
if (this.overridden) {
|
||||
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
|
||||
}
|
||||
this.context.registerBeanDefinition("test", rbd);
|
||||
this.context.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ITestBean prototypeCreation(BenchmarkState state) {
|
||||
TestBean tb = state.context.getBean("test", TestBean.class);
|
||||
return tb.getSpouse();
|
||||
}
|
||||
|
||||
|
||||
private static class ResourceAnnotatedTestBean extends org.springframework.beans.testfixture.beans.TestBean {
|
||||
|
||||
@Override
|
||||
@Resource
|
||||
@SuppressWarnings("deprecation")
|
||||
@org.springframework.beans.factory.annotation.Required
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
super.setSpouse(spouse);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AutowiredAnnotatedTestBean extends TestBean {
|
||||
|
||||
@Override
|
||||
@Autowired
|
||||
@SuppressWarnings("deprecation")
|
||||
@org.springframework.beans.factory.annotation.Required
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
super.setSpouse(spouse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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
|
||||
*
|
||||
* https://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.context.expression;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* Benchmark for application context expressions resolution during prototype bean creation.
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
public class ApplicationContextExpressionBenchmark {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class BenchmarkState {
|
||||
|
||||
public GenericApplicationContext context;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
System.getProperties().put("name", "juergen");
|
||||
System.getProperties().put("country", "UK");
|
||||
this.context = new GenericApplicationContext();
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
|
||||
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue("#{systemProperties.name}");
|
||||
rbd.getPropertyValues().add("country", "#{systemProperties.country}");
|
||||
this.context.registerBeanDefinition("test", rbd);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void teardown() {
|
||||
System.getProperties().remove("country");
|
||||
System.getProperties().remove("name");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void prototypeCreationWithSystemProperties(BenchmarkState state, Blackhole bh) {
|
||||
TestBean tb = (TestBean) state.context.getBean("test");
|
||||
bh.consume(tb.getName());
|
||||
bh.consume(tb.getCountry());
|
||||
}
|
||||
}
|
||||
+27
-3
@@ -21,7 +21,6 @@ import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -380,7 +379,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
|
||||
Cache cache = context.getCaches().iterator().next();
|
||||
try {
|
||||
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
|
||||
return wrapCacheValue(method, handleSynchronizedGet(invoker, key, cache));
|
||||
}
|
||||
catch (Cache.ValueRetrievalException ex) {
|
||||
// Directly propagate ThrowableWrapper from the invoker,
|
||||
@@ -403,7 +402,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
|
||||
|
||||
// Collect puts from any @Cacheable miss, if no cached item is found
|
||||
List<CachePutRequest> cachePutRequests = new LinkedList<>();
|
||||
List<CachePutRequest> cachePutRequests = new ArrayList<>();
|
||||
if (cacheHit == null) {
|
||||
collectPutRequests(contexts.get(CacheableOperation.class),
|
||||
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
|
||||
@@ -437,6 +436,22 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object handleSynchronizedGet(CacheOperationInvoker invoker, Object key, Cache cache) {
|
||||
InvocationAwareResult invocationResult = new InvocationAwareResult();
|
||||
Object result = cache.get(key, () -> {
|
||||
invocationResult.invoked = true;
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("No cache entry for key '" + key + "' in cache " + cache.getName());
|
||||
}
|
||||
return unwrapReturnValue(invokeOperation(invoker));
|
||||
});
|
||||
if (!invocationResult.invoked && logger.isTraceEnabled()) {
|
||||
logger.trace("Cache entry for key '" + key + "' found in cache '" + cache.getName() + "'");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object wrapCacheValue(Method method, @Nullable Object cacheValue) {
|
||||
if (method.getReturnType() == Optional.class &&
|
||||
@@ -870,4 +885,13 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal holder class for recording that a cache method was invoked.
|
||||
*/
|
||||
private static class InvocationAwareResult {
|
||||
|
||||
boolean invoked;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user