diff --git a/docs/404.html b/docs/404.html index 0b9ad75f..1871fba3 100644 --- a/docs/404.html +++ b/docs/404.html @@ -8,13 +8,13 @@ - - + + -

404

How did we get here?
+ - + diff --git "a/docs/advance/5.1.\347\274\223\345\255\230.html" "b/docs/advance/5.1.\347\274\223\345\255\230.html" index e10d1b4f..417535e7 100644 --- "a/docs/advance/5.1.\347\274\223\345\255\230.html" +++ "b/docs/advance/5.1.\347\274\223\345\255\230.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/advance/5.2.\347\273\204\345\220\210\346\263\250\350\247\243.html" "b/docs/advance/5.2.\347\273\204\345\220\210\346\263\250\350\247\243.html" index 6aae73d0..fef81f4a 100644 --- "a/docs/advance/5.2.\347\273\204\345\220\210\346\263\250\350\247\243.html" +++ "b/docs/advance/5.2.\347\273\204\345\220\210\346\263\250\350\247\243.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/advance/5.3.\345\256\271\345\231\250\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237\345\233\236\350\260\203.html" "b/docs/advance/5.3.\345\256\271\345\231\250\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237\345\233\236\350\260\203.html" index e569990c..5fcb366d 100644 --- "a/docs/advance/5.3.\345\256\271\345\231\250\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237\345\233\236\350\260\203.html" +++ "b/docs/advance/5.3.\345\256\271\345\231\250\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237\345\233\236\350\260\203.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/advance/5.4.\345\217\215\345\260\204\345\267\245\345\216\202.html" "b/docs/advance/5.4.\345\217\215\345\260\204\345\267\245\345\216\202.html" index c53a87ce..c1a7b35d 100644 --- "a/docs/advance/5.4.\345\217\215\345\260\204\345\267\245\345\216\202.html" +++ "b/docs/advance/5.4.\345\217\215\345\260\204\345\267\245\345\216\202.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/advance/5.5.\346\223\215\344\275\234\346\263\250\350\247\243\350\247\243\346\236\220\345\231\250.html" "b/docs/advance/5.5.\346\223\215\344\275\234\346\263\250\350\247\243\350\247\243\346\236\220\345\231\250.html" index a75e2a2e..00449d49 100644 --- "a/docs/advance/5.5.\346\223\215\344\275\234\346\263\250\350\247\243\350\247\243\346\236\220\345\231\250.html" +++ "b/docs/advance/5.5.\346\223\215\344\275\234\346\263\250\350\247\243\350\247\243\346\236\220\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/advance/5.6.\347\261\273\345\236\213\350\275\254\346\215\242.html" "b/docs/advance/5.6.\347\261\273\345\236\213\350\275\254\346\215\242.html" index 1d174c12..afe2bd08 100644 --- "a/docs/advance/5.6.\347\261\273\345\236\213\350\275\254\346\215\242.html" +++ "b/docs/advance/5.6.\347\261\273\345\236\213\350\275\254\346\215\242.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git a/docs/assets/css/0.styles.ff64e91f.css b/docs/assets/css/0.styles.97dde16e.css similarity index 95% rename from docs/assets/css/0.styles.ff64e91f.css rename to docs/assets/css/0.styles.97dde16e.css index 36a3538b..690d60c6 100644 --- a/docs/assets/css/0.styles.ff64e91f.css +++ b/docs/assets/css/0.styles.97dde16e.css @@ -1 +1 @@ -code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#282c34}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:3.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#3eaf7c}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}#nprogress{pointer-events:none}#nprogress .bar{background:#3eaf7c;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #3eaf7c,0 0 5px #3eaf7c;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#3eaf7c transparent transparent #3eaf7c;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.home{padding:3.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#3eaf7c;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #389d70}.home .hero .action-button:hover{background-color:#4abf8a}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/crane4j/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#3eaf7c}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#3eaf7c}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title,.dropdown-wrapper .mobile-dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:#2c3e50}.dropdown-wrapper .dropdown-title:hover,.dropdown-wrapper .mobile-dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow,.dropdown-wrapper .mobile-dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .mobile-dropdown-title{display:none;font-weight:600}.dropdown-wrapper .mobile-dropdown-title font-size inherit:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:1rem 1.5rem .45rem 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #3eaf7c;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{display:none}.dropdown-wrapper .mobile-dropdown-title{display:block}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper.open:blur{display:none}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#3eaf7c}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #46bd87}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#767676}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page{padding-bottom:2rem;display:block}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-heading.clickable:hover{color:#3eaf7c}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#3eaf7c}a.sidebar-link.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}.badge[data-v-15b7b770]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-15b7b770],.badge.tip[data-v-15b7b770],.badge[data-v-15b7b770]{background-color:#42b983}.badge.error[data-v-15b7b770]{background-color:#da5961}.badge.warn[data-v-15b7b770],.badge.warning[data-v-15b7b770],.badge.yellow[data-v-15b7b770]{background-color:#e7c000}.badge+.badge[data-v-15b7b770]{margin-left:5px}.theme-code-block[data-v-759a7d02]{display:none}.theme-code-block__active[data-v-759a7d02]{display:block}.theme-code-block>pre[data-v-759a7d02]{background-color:orange}.theme-code-group__nav[data-v-deefee04]{margin-bottom:-35px;background-color:#282c34;padding-bottom:22px;border-top-left-radius:6px;border-top-right-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__ul[data-v-deefee04]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__nav-tab[data-v-deefee04]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:hsla(0,0%,100%,.9);font-weight:600}.theme-code-group__nav-tab-active[data-v-deefee04]{border-bottom:1px solid #42b983}.pre-blank[data-v-deefee04]{color:#42b983} \ No newline at end of file +code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#282c34}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:3.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#3eaf7c}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}#nprogress{pointer-events:none}#nprogress .bar{background:#3eaf7c;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #3eaf7c,0 0 5px #3eaf7c;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#3eaf7c transparent transparent #3eaf7c;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.home{padding:3.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#3eaf7c;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #389d70}.home .hero .action-button:hover{background-color:#4abf8a}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/crane4j/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#3eaf7c}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#3eaf7c}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title,.dropdown-wrapper .mobile-dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:#2c3e50}.dropdown-wrapper .dropdown-title:hover,.dropdown-wrapper .mobile-dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow,.dropdown-wrapper .mobile-dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .mobile-dropdown-title{display:none;font-weight:600}.dropdown-wrapper .mobile-dropdown-title font-size inherit:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:1rem 1.5rem .45rem 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #3eaf7c;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{display:none}.dropdown-wrapper .mobile-dropdown-title{display:block}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper.open:blur{display:none}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#3eaf7c}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #46bd87}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#767676}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page{padding-bottom:2rem;display:block}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-heading.clickable:hover{color:#3eaf7c}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#3eaf7c}a.sidebar-link.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}.theme-code-group__nav[data-v-deefee04]{margin-bottom:-35px;background-color:#282c34;padding-bottom:22px;border-top-left-radius:6px;border-top-right-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__ul[data-v-deefee04]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__nav-tab[data-v-deefee04]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:hsla(0,0%,100%,.9);font-weight:600}.theme-code-group__nav-tab-active[data-v-deefee04]{border-bottom:1px solid #42b983}.pre-blank[data-v-deefee04]{color:#42b983}.theme-code-block[data-v-759a7d02]{display:none}.theme-code-block__active[data-v-759a7d02]{display:block}.theme-code-block>pre[data-v-759a7d02]{background-color:orange}.badge[data-v-15b7b770]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-15b7b770],.badge.tip[data-v-15b7b770],.badge[data-v-15b7b770]{background-color:#42b983}.badge.error[data-v-15b7b770]{background-color:#da5961}.badge.warn[data-v-15b7b770],.badge.warning[data-v-15b7b770],.badge.yellow[data-v-15b7b770]{background-color:#e7c000}.badge+.badge[data-v-15b7b770]{margin-left:5px} \ No newline at end of file diff --git a/docs/assets/js/11.620718d0.js b/docs/assets/js/11.c34b03c2.js similarity index 99% rename from docs/assets/js/11.620718d0.js rename to docs/assets/js/11.c34b03c2.js index cc9d4eaa..1d3cd6fd 100644 --- a/docs/assets/js/11.620718d0.js +++ b/docs/assets/js/11.c34b03c2.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{289:function(a,t,s){"use strict";s.r(t);var n=s(14),e=Object(n.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[a._v("#")]),a._v(" 概述")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,每个缓存对应一个 "),t("code",[a._v("Cache")]),a._v(" 对象,用于提供缓存的读写功能。数据源容器通过持有 "),t("code",[a._v("Cache")]),a._v(" 对象来实现对缓存的操作。所有的 "),t("code",[a._v("Cache")]),a._v(" 对象都由全局的缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 进行管理。")]),a._v(" "),t("p",[a._v("缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 负责创建、配置和管理缓存对象。它提供了一组接口和方法,用于获取、创建、删除和管理缓存。通过 "),t("code",[a._v("CacheManager")]),a._v(",我们可以对缓存进行统一的管理和控制。")]),a._v(" "),t("p",[a._v("下图展示了 "),t("code",[a._v("Cache")]),a._v("、数据源容器和缓存管理器之间的关系:")]),a._v(" "),t("p",[t("img",{attrs:{src:"https://img.xiajibagao.top/image-20230225011748030.png",alt:"缓存结构"}})]),a._v(" "),t("p",[a._v("在这个结构中,数据源容器通过 "),t("code",[a._v("Cache")]),a._v(" 对象与缓存进行交互,而 "),t("code",[a._v("Cache")]),a._v(" 对象则由缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 管理和配置。")]),a._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),t("p",[a._v("在目前的版本中,由于缺乏 redis 支持,以及缺少细粒度控制缓存过期时间等原因,缓存的实用价值依然有限,在后续版本将会进一步完善它。")])]),a._v(" "),t("h2",{attrs:{id:"_5-1-1-缓存管理器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-1-缓存管理器"}},[a._v("#")]),a._v(" 5.1.1.缓存管理器")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,缓存功能由缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 和具体的缓存对象 "),t("code",[a._v("Cache")]),a._v(" 共同完成。缓存管理器负责管理缓存对象的创建和销毁,而缓存对象提供具体的读写功能。")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 默认提供了两种缓存管理器实现:")]),a._v(" "),t("ul",[t("li",[t("code",[a._v("ConcurrentMapCacheManager")]),a._v(":基于 "),t("code",[a._v("WeakConcurrentMap")]),a._v(" 实现的缓存对象,无法设置过期策略,只能依赖 JVM 自动回收缓存。它是默认的缓存管理器;")]),a._v(" "),t("li",[t("code",[a._v("GuavaCacheManager")]),a._v(":基于 "),t("code",[a._v("Guava")]),a._v(" 的 "),t("code",[a._v("Cache")]),a._v(" 实现的缓存对象,支持配置过期时间和并发等级等选项;")])]),a._v(" "),t("p",[a._v("要替换默认的缓存管理器,可以在配置类中声明一个 "),t("code",[a._v("GuavaCacheManager")]),a._v(" 实例,并将其作为 Bean 注册到 Spring 上下文中。通过自定义的 "),t("code",[a._v("GuavaCacheManager")]),a._v(",可以配置自定义的缓存过期时间和并发级别等参数。")]),a._v(" "),t("p",[a._v("在使用缓存时,可以通过缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 创建和获取缓存对象 "),t("code",[a._v("Cache")]),a._v(",然后使用 "),t("code",[a._v("Cache")]),a._v(" 对象进行缓存的读写和销毁操作。")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[a._v('// 获取名为 "foo" 的缓存对象')]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Cache")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" cache "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getCache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 使用缓存对象进行读写操作")]),a._v("\ncache"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheKey"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\ncache"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("put")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheKey"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheValue"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v('// 销毁名为 "foo" 的缓存对象')]),a._v("\ncacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("removeCache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("需要注意的是,销毁缓存对象后,之前获取到的缓存对象仍然可以使用,但是数据可能已被清空。可以通过 "),t("code",[a._v("Cache.isExpired()")]),a._v(" 方法判断缓存是否已过期。")]),a._v(" "),t("p",[a._v("缓存管理器和缓存对象一般不直接使用,而是与缓存容器等机制结合使用,以实现更高级的缓存功能。")]),a._v(" "),t("h2",{attrs:{id:"_5-1-2-结合数据源容器使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-2-结合数据源容器使用"}},[a._v("#")]),a._v(" 5.1.2.结合数据源容器使用")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,数据源缓存容器基于缓存容器包装类 "),t("code",[a._v("CacheableContainer")]),a._v(" 实现,它可以包装任何容器,使其具备缓存功能。")]),a._v(" "),t("p",[a._v("下面是创建数据源缓存容器的示例代码:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 1、创建一个原始容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" original "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("LambdaContainer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("forLambda")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"original"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" keys "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collections")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("emptyMap")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("///2、获取缓存管理器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),a._v(" cacheManager "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 3、基于原始容器与缓存对象,构建带有缓存功能的容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("original"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheName"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("在上述示例中,通过 "),t("code",[a._v("LambdaContainer")]),a._v(" 创建了一个原始容器 "),t("code",[a._v("original")]),a._v(",然后使用缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 和指定的缓存对象名称 "),t("code",[a._v('"cacheName"')]),a._v(",构建了带有缓存功能的容器 "),t("code",[a._v("container")]),a._v("。")]),a._v(" "),t("p",[a._v("容器缓存的粒度是 key 级别,即第一次查询 a、b,则会对 a、b 进行查询并缓存。第二次查询 a、b、c 时,只会查询 c 并将其增量添加到缓存中,而 a、b 则直接从缓存中获取。")]),a._v(" "),t("h2",{attrs:{id:"_5-1-3-配置缓存容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-配置缓存容器"}},[a._v("#")]),a._v(" 5.1.3.配置缓存容器")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,你可以通过三种方式将一个普通容器配置为缓存容器。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-1-手动替换"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-1-手动替换"}},[a._v("#")]),a._v(" 5.1.3.1. 手动替换")]),a._v(" "),t("p",[a._v("可以获取全局配置类 "),t("code",[a._v("Crane4jGlobalConfiguration")]),a._v(",然后使用 "),t("code",[a._v("replaceContainer")]),a._v(" 方法将原始的容器替换为包装后的缓存容器。")]),a._v(" "),t("p",[a._v("示例代码如下:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Crane4jGlobalConfiguration")]),a._v(" configuration "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Crane4jGlobalConfiguration")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),a._v(" cacheManager "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 将原始容器包装并替换为缓存容器")]),a._v("\nconfiguration"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("compute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"namespace"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" container"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheName"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("在上述示例中,使用 "),t("code",[a._v("Crane4jGlobalConfiguration")]),a._v(" 获取全局配置类实例,然后通过 "),t("code",[a._v("replaceContainer")]),a._v(" 方法将指定命名空间的原始容器替换为缓存容器。需要传入原始容器、缓存管理器和缓存对象的名称。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-2-添加注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-2-添加注解"}},[a._v("#")]),a._v(" 5.1.3.2. 添加注解")]),a._v(" "),t("p",[a._v("如果使用 "),t("code",[a._v("@ContainerMethod")]),a._v(" 声明的方法容器,可以在方法上添加 "),t("code",[a._v("@ContainerCache")]),a._v(" 注解或 "),t("code",[a._v("@CacheContainerMethod")]),a._v(" 组合注解,将方法容器声明为可缓存容器。")]),a._v(" "),t("p",[a._v("示例代码如下:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@ContainerCache")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 声明该方法容器为可缓存容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@ContainerMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("resultType "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("oneToManyMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("toList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),t("p",[a._v("或者使用 "),t("code",[a._v("@CacheContainerMethod")]),a._v(" 组合注解:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@CacheContainerMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("resultType "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("oneToManyMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("toList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),t("p",[a._v("方法容器创建后,会自动包装为缓存容器。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-3-配置文件"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-3-配置文件"}},[a._v("#")]),a._v(" 5.1.3.3. 配置文件")]),a._v(" "),t("p",[a._v("可以在配置文件中声明要将哪些容器包装为缓存容器。")]),a._v(" "),t("p",[a._v("示例配置如下(YAML 格式):")]),a._v(" "),t("div",{staticClass:"language-yaml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yaml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" container"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("-")]),a._v("namespace\n")])])]),t("p",[a._v("上述配置中,声明了将命名空间为 "),t("code",[a._v("container-namespace")]),a._v(" 的容器包装为缓存容器,并使用了指定的缓存名称 "),t("code",[a._v("cache-name")]),a._v("。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{287:function(a,t,s){"use strict";s.r(t);var n=s(14),e=Object(n.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[a._v("#")]),a._v(" 概述")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,每个缓存对应一个 "),t("code",[a._v("Cache")]),a._v(" 对象,用于提供缓存的读写功能。数据源容器通过持有 "),t("code",[a._v("Cache")]),a._v(" 对象来实现对缓存的操作。所有的 "),t("code",[a._v("Cache")]),a._v(" 对象都由全局的缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 进行管理。")]),a._v(" "),t("p",[a._v("缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 负责创建、配置和管理缓存对象。它提供了一组接口和方法,用于获取、创建、删除和管理缓存。通过 "),t("code",[a._v("CacheManager")]),a._v(",我们可以对缓存进行统一的管理和控制。")]),a._v(" "),t("p",[a._v("下图展示了 "),t("code",[a._v("Cache")]),a._v("、数据源容器和缓存管理器之间的关系:")]),a._v(" "),t("p",[t("img",{attrs:{src:"https://img.xiajibagao.top/image-20230225011748030.png",alt:"缓存结构"}})]),a._v(" "),t("p",[a._v("在这个结构中,数据源容器通过 "),t("code",[a._v("Cache")]),a._v(" 对象与缓存进行交互,而 "),t("code",[a._v("Cache")]),a._v(" 对象则由缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 管理和配置。")]),a._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),t("p",[a._v("在目前的版本中,由于缺乏 redis 支持,以及缺少细粒度控制缓存过期时间等原因,缓存的实用价值依然有限,在后续版本将会进一步完善它。")])]),a._v(" "),t("h2",{attrs:{id:"_5-1-1-缓存管理器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-1-缓存管理器"}},[a._v("#")]),a._v(" 5.1.1.缓存管理器")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,缓存功能由缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 和具体的缓存对象 "),t("code",[a._v("Cache")]),a._v(" 共同完成。缓存管理器负责管理缓存对象的创建和销毁,而缓存对象提供具体的读写功能。")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 默认提供了两种缓存管理器实现:")]),a._v(" "),t("ul",[t("li",[t("code",[a._v("ConcurrentMapCacheManager")]),a._v(":基于 "),t("code",[a._v("WeakConcurrentMap")]),a._v(" 实现的缓存对象,无法设置过期策略,只能依赖 JVM 自动回收缓存。它是默认的缓存管理器;")]),a._v(" "),t("li",[t("code",[a._v("GuavaCacheManager")]),a._v(":基于 "),t("code",[a._v("Guava")]),a._v(" 的 "),t("code",[a._v("Cache")]),a._v(" 实现的缓存对象,支持配置过期时间和并发等级等选项;")])]),a._v(" "),t("p",[a._v("要替换默认的缓存管理器,可以在配置类中声明一个 "),t("code",[a._v("GuavaCacheManager")]),a._v(" 实例,并将其作为 Bean 注册到 Spring 上下文中。通过自定义的 "),t("code",[a._v("GuavaCacheManager")]),a._v(",可以配置自定义的缓存过期时间和并发级别等参数。")]),a._v(" "),t("p",[a._v("在使用缓存时,可以通过缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 创建和获取缓存对象 "),t("code",[a._v("Cache")]),a._v(",然后使用 "),t("code",[a._v("Cache")]),a._v(" 对象进行缓存的读写和销毁操作。")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[a._v('// 获取名为 "foo" 的缓存对象')]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Cache")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" cache "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getCache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 使用缓存对象进行读写操作")]),a._v("\ncache"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheKey"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\ncache"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("put")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheKey"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheValue"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v('// 销毁名为 "foo" 的缓存对象')]),a._v("\ncacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("removeCache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("需要注意的是,销毁缓存对象后,之前获取到的缓存对象仍然可以使用,但是数据可能已被清空。可以通过 "),t("code",[a._v("Cache.isExpired()")]),a._v(" 方法判断缓存是否已过期。")]),a._v(" "),t("p",[a._v("缓存管理器和缓存对象一般不直接使用,而是与缓存容器等机制结合使用,以实现更高级的缓存功能。")]),a._v(" "),t("h2",{attrs:{id:"_5-1-2-结合数据源容器使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-2-结合数据源容器使用"}},[a._v("#")]),a._v(" 5.1.2.结合数据源容器使用")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,数据源缓存容器基于缓存容器包装类 "),t("code",[a._v("CacheableContainer")]),a._v(" 实现,它可以包装任何容器,使其具备缓存功能。")]),a._v(" "),t("p",[a._v("下面是创建数据源缓存容器的示例代码:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 1、创建一个原始容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" original "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("LambdaContainer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("forLambda")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"original"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" keys "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collections")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("emptyMap")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("///2、获取缓存管理器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),a._v(" cacheManager "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 3、基于原始容器与缓存对象,构建带有缓存功能的容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("original"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheName"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("在上述示例中,通过 "),t("code",[a._v("LambdaContainer")]),a._v(" 创建了一个原始容器 "),t("code",[a._v("original")]),a._v(",然后使用缓存管理器 "),t("code",[a._v("CacheManager")]),a._v(" 和指定的缓存对象名称 "),t("code",[a._v('"cacheName"')]),a._v(",构建了带有缓存功能的容器 "),t("code",[a._v("container")]),a._v("。")]),a._v(" "),t("p",[a._v("容器缓存的粒度是 key 级别,即第一次查询 a、b,则会对 a、b 进行查询并缓存。第二次查询 a、b、c 时,只会查询 c 并将其增量添加到缓存中,而 a、b 则直接从缓存中获取。")]),a._v(" "),t("h2",{attrs:{id:"_5-1-3-配置缓存容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-配置缓存容器"}},[a._v("#")]),a._v(" 5.1.3.配置缓存容器")]),a._v(" "),t("p",[a._v("在 "),t("code",[a._v("crane4j")]),a._v(" 中,你可以通过三种方式将一个普通容器配置为缓存容器。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-1-手动替换"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-1-手动替换"}},[a._v("#")]),a._v(" 5.1.3.1. 手动替换")]),a._v(" "),t("p",[a._v("可以获取全局配置类 "),t("code",[a._v("Crane4jGlobalConfiguration")]),a._v(",然后使用 "),t("code",[a._v("replaceContainer")]),a._v(" 方法将原始的容器替换为包装后的缓存容器。")]),a._v(" "),t("p",[a._v("示例代码如下:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Crane4jGlobalConfiguration")]),a._v(" configuration "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Crane4jGlobalConfiguration")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),a._v(" cacheManager "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("StringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 将原始容器包装并替换为缓存容器")]),a._v("\nconfiguration"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("compute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"namespace"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CacheableContainer")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" container"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" cacheManager"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cacheName"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),t("p",[a._v("在上述示例中,使用 "),t("code",[a._v("Crane4jGlobalConfiguration")]),a._v(" 获取全局配置类实例,然后通过 "),t("code",[a._v("replaceContainer")]),a._v(" 方法将指定命名空间的原始容器替换为缓存容器。需要传入原始容器、缓存管理器和缓存对象的名称。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-2-添加注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-2-添加注解"}},[a._v("#")]),a._v(" 5.1.3.2. 添加注解")]),a._v(" "),t("p",[a._v("如果使用 "),t("code",[a._v("@ContainerMethod")]),a._v(" 声明的方法容器,可以在方法上添加 "),t("code",[a._v("@ContainerCache")]),a._v(" 注解或 "),t("code",[a._v("@CacheContainerMethod")]),a._v(" 组合注解,将方法容器声明为可缓存容器。")]),a._v(" "),t("p",[a._v("示例代码如下:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@ContainerCache")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 声明该方法容器为可缓存容器")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@ContainerMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("resultType "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("oneToManyMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("toList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),t("p",[a._v("或者使用 "),t("code",[a._v("@CacheContainerMethod")]),a._v(" 组合注解:")]),a._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@CacheContainerMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("resultType "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("oneToManyMethod")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("new")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("toList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),t("p",[a._v("方法容器创建后,会自动包装为缓存容器。")]),a._v(" "),t("h3",{attrs:{id:"_5-1-3-3-配置文件"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-3-3-配置文件"}},[a._v("#")]),a._v(" 5.1.3.3. 配置文件")]),a._v(" "),t("p",[a._v("可以在配置文件中声明要将哪些容器包装为缓存容器。")]),a._v(" "),t("p",[a._v("示例配置如下(YAML 格式):")]),a._v(" "),t("div",{staticClass:"language-yaml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yaml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" container"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("-")]),a._v("namespace\n")])])]),t("p",[a._v("上述配置中,声明了将命名空间为 "),t("code",[a._v("container-namespace")]),a._v(" 的容器包装为缓存容器,并使用了指定的缓存名称 "),t("code",[a._v("cache-name")]),a._v("。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/13.ba9f587a.js b/docs/assets/js/13.75a014e9.js similarity index 99% rename from docs/assets/js/13.ba9f587a.js rename to docs/assets/js/13.75a014e9.js index ca1b3d79..f0b9ec37 100644 --- a/docs/assets/js/13.ba9f587a.js +++ b/docs/assets/js/13.75a014e9.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[13],{287:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"_5-3-1-容器生命周期处理器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-1-容器生命周期处理器"}},[t._v("#")]),t._v(" 5.3.1.容器生命周期处理器")]),t._v(" "),s("p",[t._v("参照 Spring 的回调机制,"),s("code",[t._v("crane4j")]),t._v(" 也提供了特殊的回调接口 "),s("code",[t._v("ContainerLifecycleProcessor")]),t._v(",它可以用于感知并干涉容器生命周期中的三个关键节点:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("whenRegistered")]),t._v(":容器注册前回调,通过该方法获得要注册的容器示例或工厂方法;")]),t._v(" "),s("li",[s("code",[t._v("whenCreated")]),t._v(":容器创建后,通过该方法可以获取创建后即将加入缓存的容器实例;")]),t._v(" "),s("li",[s("code",[t._v("whenDestroyed")]),t._v(":容器销毁后回调,通过该方法可以获得被替换或者删除的容器;")])]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 默认提供了三种处理器实现:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("CacheableContainerProcessor")]),t._v(":在用户的容器注册前,将会把要注册的容器对象包装并替换具备缓存功能的增强容器;")]),t._v(" "),s("li",[s("code",[t._v("ContainerRegisterLogger")]),t._v(":在容器生命周期的三个关键节点输出相关信息;")]),t._v(" "),s("li",[s("code",[t._v("ContainerInstanceLifecycleProcessor")]),t._v(":用于支持 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 的 "),s("code",[t._v("init")]),t._v(" 和 "),s("code",[t._v("destroy")]),t._v(" 方法。")])]),t._v(" "),s("p",[t._v("用户也可以自己实现 "),s("code",[t._v("CacheableContainerProcessor")]),t._v(",并将其声明在 spring 上下文中以便自动注册,或者获得全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 后,调用 "),s("code",[t._v("addContainerLifecycleProcessor")]),t._v(" 方法手动注册。")]),t._v(" "),s("h2",{attrs:{id:"_5-3-2-容器的生命周期回调"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-2-容器的生命周期回调"}},[t._v("#")]),t._v(" 5.3.2.容器的生命周期回调")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,容器本身具备针对自身生命周期的回调方法,仅需让实现类实现 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口,并在实现类中实现相应的回调方法即可。")]),t._v(" "),s("p",[t._v("以下是一个示例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implements")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Lifecycle")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"AllDictContainer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictService")]),t._v(" dictService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictDO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" allDicts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 初始化方法")]),t._v("\n allDicts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dictService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stream")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictDO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 销毁方法")]),t._v("\n allDicts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clear")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" allDicts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们创建了一个缓存全部字典项的容器 "),s("code",[t._v("Foo")]),t._v(",它实现了 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口。在容器被使用时,会调用 "),s("code",[t._v("init()")]),t._v(" 方法进行初始化,该方法会查询并缓存字典值。在容器被销毁时,会调用 "),s("code",[t._v("destroy()")]),t._v(" 方法进行销毁,该方法会清空缓存。")]),t._v(" "),s("p",[t._v("通过实现 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口,并在相应的回调方法中编写初始化和销毁逻辑,你可以在制容器的生命周期中实现自定义的初始化和销毁操作。这对于在容器被使用前后执行一些特定逻辑非常有用。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[13],{286:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"_5-3-1-容器生命周期处理器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-1-容器生命周期处理器"}},[t._v("#")]),t._v(" 5.3.1.容器生命周期处理器")]),t._v(" "),s("p",[t._v("参照 Spring 的回调机制,"),s("code",[t._v("crane4j")]),t._v(" 也提供了特殊的回调接口 "),s("code",[t._v("ContainerLifecycleProcessor")]),t._v(",它可以用于感知并干涉容器生命周期中的三个关键节点:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("whenRegistered")]),t._v(":容器注册前回调,通过该方法获得要注册的容器示例或工厂方法;")]),t._v(" "),s("li",[s("code",[t._v("whenCreated")]),t._v(":容器创建后,通过该方法可以获取创建后即将加入缓存的容器实例;")]),t._v(" "),s("li",[s("code",[t._v("whenDestroyed")]),t._v(":容器销毁后回调,通过该方法可以获得被替换或者删除的容器;")])]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 默认提供了三种处理器实现:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("CacheableContainerProcessor")]),t._v(":在用户的容器注册前,将会把要注册的容器对象包装并替换具备缓存功能的增强容器;")]),t._v(" "),s("li",[s("code",[t._v("ContainerRegisterLogger")]),t._v(":在容器生命周期的三个关键节点输出相关信息;")]),t._v(" "),s("li",[s("code",[t._v("ContainerInstanceLifecycleProcessor")]),t._v(":用于支持 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 的 "),s("code",[t._v("init")]),t._v(" 和 "),s("code",[t._v("destroy")]),t._v(" 方法。")])]),t._v(" "),s("p",[t._v("用户也可以自己实现 "),s("code",[t._v("CacheableContainerProcessor")]),t._v(",并将其声明在 spring 上下文中以便自动注册,或者获得全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 后,调用 "),s("code",[t._v("addContainerLifecycleProcessor")]),t._v(" 方法手动注册。")]),t._v(" "),s("h2",{attrs:{id:"_5-3-2-容器的生命周期回调"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-2-容器的生命周期回调"}},[t._v("#")]),t._v(" 5.3.2.容器的生命周期回调")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,容器本身具备针对自身生命周期的回调方法,仅需让实现类实现 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口,并在实现类中实现相应的回调方法即可。")]),t._v(" "),s("p",[t._v("以下是一个示例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implements")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Lifecycle")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"AllDictContainer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictService")]),t._v(" dictService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictDO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" allDicts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 初始化方法")]),t._v("\n allDicts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dictService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stream")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DictDO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 销毁方法")]),t._v("\n allDicts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clear")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" allDicts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们创建了一个缓存全部字典项的容器 "),s("code",[t._v("Foo")]),t._v(",它实现了 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口。在容器被使用时,会调用 "),s("code",[t._v("init()")]),t._v(" 方法进行初始化,该方法会查询并缓存字典值。在容器被销毁时,会调用 "),s("code",[t._v("destroy()")]),t._v(" 方法进行销毁,该方法会清空缓存。")]),t._v(" "),s("p",[t._v("通过实现 "),s("code",[t._v("Container.Lifecycle")]),t._v(" 接口,并在相应的回调方法中编写初始化和销毁逻辑,你可以在制容器的生命周期中实现自定义的初始化和销毁操作。这对于在容器被使用前后执行一些特定逻辑非常有用。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/14.a42c75b1.js b/docs/assets/js/14.0c98bb09.js similarity index 99% rename from docs/assets/js/14.a42c75b1.js rename to docs/assets/js/14.0c98bb09.js index 84705601..6f191f52 100644 --- a/docs/assets/js/14.a42c75b1.js +++ b/docs/assets/js/14.0c98bb09.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{288:function(t,a,s){"use strict";s.r(a);var e=s(14),r=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"反射工厂"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#反射工厂"}},[t._v("#")]),t._v(" 反射工厂")]),t._v(" "),a("p",[t._v("在 "),a("code",[t._v("crane4j")]),t._v(" 中,提供了属性操作者 "),a("code",[t._v("PropertyOperator")]),t._v(" 组件,类似于 MyBatis 的反射工厂,用于统一管理框架各处的反射调用操作。")]),t._v(" "),a("p",[t._v("它被用于支持包括装配操作执行器、拆卸操作执行器、方法数据源容器以及自动填充切面中的各种属性操作功能。")]),t._v(" "),a("p",[t._v("默认情况下,"),a("code",[t._v("PropertyOperator")]),t._v(" 提供了五个实现:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("ReflectivePropertyOperator")]),t._v(":基于原生反射的普通反射属性操作者;")]),t._v(" "),a("li",[a("code",[t._v("AsmReflectivePropertyOperator")]),t._v(":基于 "),a("code",[t._v("ReflectAsm")]),t._v(" 的字节码反射属性操作者;")]),t._v(" "),a("li",[a("code",[t._v("CacheablePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持 "),a("code",[t._v("getter")]),t._v(" 和 "),a("code",[t._v("setter")]),t._v(" 缓存;")]),t._v(" "),a("li",[a("code",[t._v("MapAccessiblePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持读写 "),a("code",[t._v("Map")]),t._v(" 集合;")]),t._v(" "),a("li",[a("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持通过链式操作符读写嵌套对象属性;")])]),t._v(" "),a("p",[t._v("如果你想替换默认的 "),a("code",[t._v("PropertyOperator")]),t._v(" 实现,可以在 Spring 配置类中重新声明一个 "),a("code",[t._v("PropertyOperator")]),t._v(",并返回自定义的实现:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Bean")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("customPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("如果在非 Spring 环境中,可以获取全局配置对象 "),a("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 并手动配置自定义的 "),a("code",[t._v("PropertyOperator")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconfiguration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("另外,如果你希望对现有的 "),a("code",[t._v("PropertyOperator")]),t._v(" 进行增强,例如支持读写 "),a("code",[t._v("Map")]),t._v(" 集合或通过链式操作符读写嵌套对象属性,可以使用默认提供的包装类对属性操作者进行包装:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MapAccessiblePropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainAccessiblePropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("请注意,包装时的顺序很重要,需要根据你的需求和使用情况选择正确的顺序。")])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{301:function(t,a,s){"use strict";s.r(a);var e=s(14),r=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"反射工厂"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#反射工厂"}},[t._v("#")]),t._v(" 反射工厂")]),t._v(" "),a("p",[t._v("在 "),a("code",[t._v("crane4j")]),t._v(" 中,提供了属性操作者 "),a("code",[t._v("PropertyOperator")]),t._v(" 组件,类似于 MyBatis 的反射工厂,用于统一管理框架各处的反射调用操作。")]),t._v(" "),a("p",[t._v("它被用于支持包括装配操作执行器、拆卸操作执行器、方法数据源容器以及自动填充切面中的各种属性操作功能。")]),t._v(" "),a("p",[t._v("默认情况下,"),a("code",[t._v("PropertyOperator")]),t._v(" 提供了五个实现:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("ReflectivePropertyOperator")]),t._v(":基于原生反射的普通反射属性操作者;")]),t._v(" "),a("li",[a("code",[t._v("AsmReflectivePropertyOperator")]),t._v(":基于 "),a("code",[t._v("ReflectAsm")]),t._v(" 的字节码反射属性操作者;")]),t._v(" "),a("li",[a("code",[t._v("CacheablePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持 "),a("code",[t._v("getter")]),t._v(" 和 "),a("code",[t._v("setter")]),t._v(" 缓存;")]),t._v(" "),a("li",[a("code",[t._v("MapAccessiblePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持读写 "),a("code",[t._v("Map")]),t._v(" 集合;")]),t._v(" "),a("li",[a("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(":装饰器,在原有功能的基础上支持通过链式操作符读写嵌套对象属性;")])]),t._v(" "),a("p",[t._v("如果你想替换默认的 "),a("code",[t._v("PropertyOperator")]),t._v(" 实现,可以在 Spring 配置类中重新声明一个 "),a("code",[t._v("PropertyOperator")]),t._v(",并返回自定义的实现:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Bean")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("customPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("如果在非 Spring 环境中,可以获取全局配置对象 "),a("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 并手动配置自定义的 "),a("code",[t._v("PropertyOperator")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconfiguration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("另外,如果你希望对现有的 "),a("code",[t._v("PropertyOperator")]),t._v(" 进行增强,例如支持读写 "),a("code",[t._v("Map")]),t._v(" 集合或通过链式操作符读写嵌套对象属性,可以使用默认提供的包装类对属性操作者进行包装:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomPropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MapAccessiblePropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainAccessiblePropertyOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("请注意,包装时的顺序很重要,需要根据你的需求和使用情况选择正确的顺序。")])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/15.d0af17d5.js b/docs/assets/js/15.baaa7e0e.js similarity index 98% rename from docs/assets/js/15.d0af17d5.js rename to docs/assets/js/15.baaa7e0e.js index 798ef0f7..ef0a59b5 100644 --- a/docs/assets/js/15.d0af17d5.js +++ b/docs/assets/js/15.baaa7e0e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[15],{286:function(e,v,_){"use strict";_.r(v);var o=_(14),n=Object(o.a)({},(function(){var e=this,v=e._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[v("h2",{attrs:{id:"操作注解解析器"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#操作注解解析器"}},[e._v("#")]),e._v(" 操作注解解析器")]),e._v(" "),v("p",[e._v("在"),v("code",[e._v("crane4j")]),e._v("中,通过各种注解去声明操作配置,比如 "),v("code",[e._v("@Assemble")]),e._v("、"),v("code",[e._v("@Disassemble")]),e._v("、"),v("code",[e._v("@AssembleEnum")]),e._v(" 和 "),v("code",[e._v("@AssembleMp")]),e._v(",我们称这用于声明操作的注解为"),v("strong",[e._v("操作注解")]),e._v("。它们底层实际上依赖于解析器中对应的操作注解处理器 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 实现。")]),e._v(" "),v("p",[v("code",[e._v("crane4j")]),e._v(" 在这部分功能基于典型的责任链模式实现,在开始解析配置前,我们注册一系列操作注解处理器 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 到 "),v("code",[e._v("BeanOperationParser")]),e._v(" 中,每个解析器都用于解析一组特定的注解。")]),e._v(" "),v("p",[e._v("当我们将一个需要解析的 "),v("code",[e._v("AnnotatedElement")]),e._v(" 传递给"),v("code",[e._v("Parser")]),e._v("时,"),v("code",[e._v("Parser")]),e._v(" 将创建一个 "),v("code",[e._v("BeanOperations")]),e._v(" 配置对象,并驱动它在处理器链上流转。每个解析器根据规则将 "),v("code",[e._v("AnnotatedElement")]),e._v(" 上的特定注解解析为对应的装配或拆卸配置。")]),e._v(" "),v("p",[e._v("下图展示了解析器的工作流程:")]),e._v(" "),v("p",[v("img",{attrs:{src:"http://img.xiajibagao.top/%E6%97%A0%E6%A0%87%E9%A2%98-2023-06-04-1303.png",alt:""}})]),e._v(" "),v("p",[v("code",[e._v("crane4j")]),e._v("目前提供了四个内置的操作注解处理器:")]),e._v(" "),v("ul",[v("li",[v("code",[e._v("AssembleAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@Assemble")]),e._v("注解,生成装配操作;")]),e._v(" "),v("li",[v("code",[e._v("DisassembleAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@Disassemble")]),e._v("注解,生成拆卸操作;")]),e._v(" "),v("li",[v("code",[e._v("AssembleEnumAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@AssembleEnum")]),e._v("注解,生成装配操作;")]),e._v(" "),v("li",[v("code",[e._v("AssembleMpAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@AssembleMp")]),e._v("注解,生成以 MyBatis-Plus 查询方法作为数据源的装配操作;")])]),e._v(" "),v("p",[e._v("如果用户希望支持处理自定义的操作注解,可以实现 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 接口创建自定义解析器。")]),e._v(" "),v("p",[e._v("在Spring环境中,只需将自定义解析器交给Spring管理,它会在项目启动后自动注册到"),v("code",[e._v("Parser")]),e._v("中。如果在非Spring环境中,可以获取"),v("code",[e._v("TypeHierarchyBeanOperationParser")]),e._v(" 并调用 "),v("code",[e._v("addOperationAnnotationHandler")]),e._v(" 方法手动注册自定义解析器。")])])}),[],!1,null,null,null);v.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[15],{299:function(e,v,_){"use strict";_.r(v);var o=_(14),n=Object(o.a)({},(function(){var e=this,v=e._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[v("h2",{attrs:{id:"操作注解解析器"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#操作注解解析器"}},[e._v("#")]),e._v(" 操作注解解析器")]),e._v(" "),v("p",[e._v("在"),v("code",[e._v("crane4j")]),e._v("中,通过各种注解去声明操作配置,比如 "),v("code",[e._v("@Assemble")]),e._v("、"),v("code",[e._v("@Disassemble")]),e._v("、"),v("code",[e._v("@AssembleEnum")]),e._v(" 和 "),v("code",[e._v("@AssembleMp")]),e._v(",我们称这用于声明操作的注解为"),v("strong",[e._v("操作注解")]),e._v("。它们底层实际上依赖于解析器中对应的操作注解处理器 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 实现。")]),e._v(" "),v("p",[v("code",[e._v("crane4j")]),e._v(" 在这部分功能基于典型的责任链模式实现,在开始解析配置前,我们注册一系列操作注解处理器 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 到 "),v("code",[e._v("BeanOperationParser")]),e._v(" 中,每个解析器都用于解析一组特定的注解。")]),e._v(" "),v("p",[e._v("当我们将一个需要解析的 "),v("code",[e._v("AnnotatedElement")]),e._v(" 传递给"),v("code",[e._v("Parser")]),e._v("时,"),v("code",[e._v("Parser")]),e._v(" 将创建一个 "),v("code",[e._v("BeanOperations")]),e._v(" 配置对象,并驱动它在处理器链上流转。每个解析器根据规则将 "),v("code",[e._v("AnnotatedElement")]),e._v(" 上的特定注解解析为对应的装配或拆卸配置。")]),e._v(" "),v("p",[e._v("下图展示了解析器的工作流程:")]),e._v(" "),v("p",[v("img",{attrs:{src:"http://img.xiajibagao.top/%E6%97%A0%E6%A0%87%E9%A2%98-2023-06-04-1303.png",alt:""}})]),e._v(" "),v("p",[v("code",[e._v("crane4j")]),e._v("目前提供了四个内置的操作注解处理器:")]),e._v(" "),v("ul",[v("li",[v("code",[e._v("AssembleAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@Assemble")]),e._v("注解,生成装配操作;")]),e._v(" "),v("li",[v("code",[e._v("DisassembleAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@Disassemble")]),e._v("注解,生成拆卸操作;")]),e._v(" "),v("li",[v("code",[e._v("AssembleEnumAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@AssembleEnum")]),e._v("注解,生成装配操作;")]),e._v(" "),v("li",[v("code",[e._v("AssembleMpAnnotationResolver")]),e._v(":用于解析"),v("code",[e._v("@AssembleMp")]),e._v("注解,生成以 MyBatis-Plus 查询方法作为数据源的装配操作;")])]),e._v(" "),v("p",[e._v("如果用户希望支持处理自定义的操作注解,可以实现 "),v("code",[e._v("OperationAnnotationHandler")]),e._v(" 接口创建自定义解析器。")]),e._v(" "),v("p",[e._v("在Spring环境中,只需将自定义解析器交给Spring管理,它会在项目启动后自动注册到"),v("code",[e._v("Parser")]),e._v("中。如果在非Spring环境中,可以获取"),v("code",[e._v("TypeHierarchyBeanOperationParser")]),e._v(" 并调用 "),v("code",[e._v("addOperationAnnotationHandler")]),e._v(" 方法手动注册自定义解析器。")])])}),[],!1,null,null,null);v.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/16.3b496ad3.js b/docs/assets/js/16.95301799.js similarity index 97% rename from docs/assets/js/16.3b496ad3.js rename to docs/assets/js/16.95301799.js index 88bc97da..2390b85f 100644 --- a/docs/assets/js/16.3b496ad3.js +++ b/docs/assets/js/16.95301799.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{291:function(e,r,v){"use strict";v.r(r);var t=v(14),o=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"类型转换"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#类型转换"}},[e._v("#")]),e._v(" 类型转换")]),e._v(" "),r("p",[e._v("在 "),r("code",[e._v("crane4j")]),e._v(" 中有不少需要通过反射调用有参方法的场景,包括且不限于:")]),e._v(" "),r("ul",[r("li",[e._v("在字段映射时调用的 "),r("code",[e._v("setter")]),e._v(" 方法;")]),e._v(" "),r("li",[e._v("从方法数据源容器调用适配方法以获取数据源;")]),e._v(" "),r("li",[e._v("调用操作接口以填充对象的参数;")])]),e._v(" "),r("p",[e._v("这些方法底层都依赖于类型转换器管理器 "),r("code",[e._v("ConverterManager")]),e._v(" 来实现参数的自动转换。换句话说,如果方法的参数类型是 A,而输入的参数类型是 B,"),r("code",[e._v("ConverterManager")]),e._v(" 将会自动尝试将 B 转换为 A 类型。")]),e._v(" "),r("p",[r("code",[e._v("ConverterManager")]),e._v(" 目前提供了三套实现:")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("SimpleConverterManager")]),e._v(":直接通过 "),r("code",[e._v("(R)t")]),e._v(" 这种方式强转,作用有限,基本不会在处理测试用例以外的地方使用;")]),e._v(" "),r("li",[r("code",[e._v("HutoolConverterManager")]),e._v(":基于 Hutool 的 "),r("code",[e._v("Convert")]),e._v(" 实现,参见 Hutool 参考文档中的 "),r("a",{attrs:{href:"https://hutool.cn/docs/#/core/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2-ConverterRegistry?id=%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2-converterregistry",target:"_blank",rel:"noopener noreferrer"}},[e._v("自定义类型转换-ConverterRegistry"),r("OutboundLink")],1),e._v(" 一节;")]),e._v(" "),r("li",[r("code",[e._v("SpringConverterManager")]),e._v(":基于 spring 的 "),r("code",[e._v("ConversionService")]),e._v(" 实现,在 spring 环境下默认使用该转换器;")])])])}),[],!1,null,null,null);r.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{288:function(e,r,v){"use strict";v.r(r);var t=v(14),o=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"类型转换"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#类型转换"}},[e._v("#")]),e._v(" 类型转换")]),e._v(" "),r("p",[e._v("在 "),r("code",[e._v("crane4j")]),e._v(" 中有不少需要通过反射调用有参方法的场景,包括且不限于:")]),e._v(" "),r("ul",[r("li",[e._v("在字段映射时调用的 "),r("code",[e._v("setter")]),e._v(" 方法;")]),e._v(" "),r("li",[e._v("从方法数据源容器调用适配方法以获取数据源;")]),e._v(" "),r("li",[e._v("调用操作接口以填充对象的参数;")])]),e._v(" "),r("p",[e._v("这些方法底层都依赖于类型转换器管理器 "),r("code",[e._v("ConverterManager")]),e._v(" 来实现参数的自动转换。换句话说,如果方法的参数类型是 A,而输入的参数类型是 B,"),r("code",[e._v("ConverterManager")]),e._v(" 将会自动尝试将 B 转换为 A 类型。")]),e._v(" "),r("p",[r("code",[e._v("ConverterManager")]),e._v(" 目前提供了三套实现:")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("SimpleConverterManager")]),e._v(":直接通过 "),r("code",[e._v("(R)t")]),e._v(" 这种方式强转,作用有限,基本不会在处理测试用例以外的地方使用;")]),e._v(" "),r("li",[r("code",[e._v("HutoolConverterManager")]),e._v(":基于 Hutool 的 "),r("code",[e._v("Convert")]),e._v(" 实现,参见 Hutool 参考文档中的 "),r("a",{attrs:{href:"https://hutool.cn/docs/#/core/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2-ConverterRegistry?id=%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2-converterregistry",target:"_blank",rel:"noopener noreferrer"}},[e._v("自定义类型转换-ConverterRegistry"),r("OutboundLink")],1),e._v(" 一节;")]),e._v(" "),r("li",[r("code",[e._v("SpringConverterManager")]),e._v(":基于 spring 的 "),r("code",[e._v("ConversionService")]),e._v(" 实现,在 spring 环境下默认使用该转换器;")])])])}),[],!1,null,null,null);r.default=o.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/17.4c926c46.js b/docs/assets/js/17.e7d0955f.js similarity index 99% rename from docs/assets/js/17.4c926c46.js rename to docs/assets/js/17.e7d0955f.js index 3302a592..79a4026a 100644 --- a/docs/assets/js/17.4c926c46.js +++ b/docs/assets/js/17.e7d0955f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{307:function(a,t,e){"use strict";e.r(t);var s=e(14),n=Object(s.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("p",[t("code",[a._v("crane4j")]),a._v(" 结合 SpringBoot 的配置系统,提供了一些可选的配置项。")]),a._v(" "),t("h2",{attrs:{id:"_1-3-1-反射"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-反射"}},[a._v("#")]),a._v(" 1.3.1.反射")]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-1-是否启用字节码反射"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-1-是否启用字节码反射"}},[a._v("#")]),a._v(" 1.3.1.1.是否启用字节码反射")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 通过默认引入了基于字节码的反射增强库 "),t("a",{attrs:{href:"https://github.com/EsotericSoftware/reflectasm",target:"_blank",rel:"noopener noreferrer"}},[a._v("ReflectAsm"),t("OutboundLink")],1),a._v(" ,用户可以通过 "),t("code",[a._v("enable-asm-reflect")]),a._v(" 开启反射增强功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 启用字节码增强")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-asm-reflect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("默认为 "),t("code",[a._v("false")]),a._v(",开启后可以一定程度上提升字段映射的性能,不过对应的可能会带来额外的内存消耗。")]),a._v(" "),t("div",{staticClass:"custom-block warning"},[t("p",{staticClass:"custom-block-title"},[a._v("WARNING")]),a._v(" "),t("p",[a._v("由于兼容性问题,该配置只在 java8 的版本有效。")])]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-2-是否支持处理map对象"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-2-是否支持处理map对象"}},[a._v("#")]),a._v(" 1.3.1.2.是否支持处理Map对象")]),a._v(" "),t("p",[a._v("是否支持对 "),t("code",[a._v("Map")]),a._v(" 对象进行属性映射,默认为 "),t("code",[a._v("true")]),a._v(":")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-map-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("如果你的项目里面没有通过 "),t("code",[a._v("crane4j")]),a._v(" 直接处理 "),t("code",[a._v("Map")]),a._v(" 或者"),t("code",[a._v("JSONObject")]),a._v(" 的需求,可以关闭它。")]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-3-是否支持链式操作符"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-3-是否支持链式操作符"}},[a._v("#")]),a._v(" 1.3.1.3.是否支持链式操作符")]),a._v(" "),t("p",[a._v("是否支持 "),t("code",[a._v("xx.xx.xx")]),a._v(" 这样的链式操作符,默认为 "),t("code",[a._v("true")]),a._v(":")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-chain-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("h2",{attrs:{id:"_1-3-2-容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-容器"}},[a._v("#")]),a._v(" 1.3.2.容器")]),a._v(" "),t("h3",{attrs:{id:"_1-3-2-1-扫描常量容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-1-扫描常量容器"}},[a._v("#")]),a._v(" 1.3.2.1.扫描常量容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将常量类也作为数据源适配为容器,因此提供了 "),t("code",[a._v("container-enum-packages")]),a._v(" 配置,用于扫描一个或多个包路径下的枚举,在应用启动后自动注册为容器:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 扫描常量包路径")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("container-constant-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.demo.constant.*\n")])])]),t("p",[a._v("关于容器部分,参见"),t("RouterLink",{attrs:{to:"/datasource/2.3.常量容器.html"}},[a._v("常量数据源容器")]),a._v("一节。")],1),a._v(" "),t("h3",{attrs:{id:"_1-3-2-2-扫描枚举容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-2-扫描枚举容器"}},[a._v("#")]),a._v(" 1.3.2.2.扫描枚举容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将枚举也作为数据源适配为容器,因此提供了 "),t("code",[a._v("container-enum-packages")]),a._v(" 配置,用于扫描一个或多个包路径下的枚举,在应用启动后自动注册为容器:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 扫描枚举包路径")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("container-enum-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.demo.constant.enums.*\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否只加载被@ContainerEnum注解的枚举")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("only-load-annotated-enum")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("关于容器部分,参见"),t("RouterLink",{attrs:{to:"/datasource/2.2.枚举容器.html"}},[a._v("枚举数据源容器")]),a._v("一节。")],1),a._v(" "),t("h3",{attrs:{id:"_1-3-2-3-扫描方法容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-3-扫描方法容器"}},[a._v("#")]),a._v(" 1.3.2.3.扫描方法容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将被 spring 管理的 "),t("code",[a._v("bean")]),a._v(" 中带有 "),t("code",[a._v("@ContainerMethod")]),a._v(" 方法也适配为容器:")]),a._v(" "),t("div",{staticClass:"language-yaml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yaml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-container")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("默认为 "),t("code",[a._v("true")]),a._v("。")]),a._v(" "),t("h3",{attrs:{id:"_1-3-2-4-容器缓存配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-4-容器缓存配置"}},[a._v("#")]),a._v(" 1.3.2.4.容器缓存配置")]),a._v(" "),t("p",[a._v("用户可以通过 "),t("code",[a._v("cache-containers")]),a._v(" 配置为指定的数据源容器添加缓存功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 声明哪些数据源需要包装为缓存")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("shared-cache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" testContainer\n")])])]),t("p",[a._v("上述示例表示,在项目启动后,通过 "),t("code",[a._v("CacheManager")]),a._v(" 为命名空间为 "),t("code",[a._v("testContainer")]),a._v(" 的容器挂载缓存空间 "),t("code",[a._v("shared-cache")]),a._v("。")]),a._v(" "),t("h2",{attrs:{id:"_1-3-3-自动填充"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-3-自动填充"}},[a._v("#")]),a._v(" 1.3.3.自动填充")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 默认支持自动方法返回值与方法入参,用户也可以通过配置自定义是否关闭该功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" \n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否启用参数自动填充")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-argument-auto-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("false")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否启用返回值自动填充")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-result-auto-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("false")]),a._v("\n")])])]),t("p",[a._v("关于自动填充,参见 "),t("RouterLink",{attrs:{to:"/execute/4.2.自动填充.html"}},[a._v("自动填充")]),a._v(" 一节。")],1),a._v(" "),t("h2",{attrs:{id:"_1-3-4-操作配置预解析"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-4-操作配置预解析"}},[a._v("#")]),a._v(" 1.3.4.操作配置预解析")]),a._v(" "),t("p",[a._v("由于操作配置对象 "),t("code",[a._v("BeanOperation")]),a._v(" 皆由对应的 "),t("code",[a._v("Class")]),a._v(" 解析而来,因此若解析器具备缓存功能,可以通过 "),t("code",[a._v("operate-entity-packages")]),a._v(" 配置实体类包路径,在执行器进行预解析,从而在后续调用时略过配置解析步骤,加快执行速度:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 操作配置预解析")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("operate-entity-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.crane4j.springboot.config.*\n")])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{290:function(a,t,e){"use strict";e.r(t);var s=e(14),n=Object(s.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("p",[t("code",[a._v("crane4j")]),a._v(" 结合 SpringBoot 的配置系统,提供了一些可选的配置项。")]),a._v(" "),t("h2",{attrs:{id:"_1-3-1-反射"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-反射"}},[a._v("#")]),a._v(" 1.3.1.反射")]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-1-是否启用字节码反射"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-1-是否启用字节码反射"}},[a._v("#")]),a._v(" 1.3.1.1.是否启用字节码反射")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 通过默认引入了基于字节码的反射增强库 "),t("a",{attrs:{href:"https://github.com/EsotericSoftware/reflectasm",target:"_blank",rel:"noopener noreferrer"}},[a._v("ReflectAsm"),t("OutboundLink")],1),a._v(" ,用户可以通过 "),t("code",[a._v("enable-asm-reflect")]),a._v(" 开启反射增强功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 启用字节码增强")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-asm-reflect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("默认为 "),t("code",[a._v("false")]),a._v(",开启后可以一定程度上提升字段映射的性能,不过对应的可能会带来额外的内存消耗。")]),a._v(" "),t("div",{staticClass:"custom-block warning"},[t("p",{staticClass:"custom-block-title"},[a._v("WARNING")]),a._v(" "),t("p",[a._v("由于兼容性问题,该配置只在 java8 的版本有效。")])]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-2-是否支持处理map对象"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-2-是否支持处理map对象"}},[a._v("#")]),a._v(" 1.3.1.2.是否支持处理Map对象")]),a._v(" "),t("p",[a._v("是否支持对 "),t("code",[a._v("Map")]),a._v(" 对象进行属性映射,默认为 "),t("code",[a._v("true")]),a._v(":")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-map-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("如果你的项目里面没有通过 "),t("code",[a._v("crane4j")]),a._v(" 直接处理 "),t("code",[a._v("Map")]),a._v(" 或者"),t("code",[a._v("JSONObject")]),a._v(" 的需求,可以关闭它。")]),a._v(" "),t("h3",{attrs:{id:"_1-3-1-3-是否支持链式操作符"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-3-是否支持链式操作符"}},[a._v("#")]),a._v(" 1.3.1.3.是否支持链式操作符")]),a._v(" "),t("p",[a._v("是否支持 "),t("code",[a._v("xx.xx.xx")]),a._v(" 这样的链式操作符,默认为 "),t("code",[a._v("true")]),a._v(":")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-chain-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("h2",{attrs:{id:"_1-3-2-容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-容器"}},[a._v("#")]),a._v(" 1.3.2.容器")]),a._v(" "),t("h3",{attrs:{id:"_1-3-2-1-扫描常量容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-1-扫描常量容器"}},[a._v("#")]),a._v(" 1.3.2.1.扫描常量容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将常量类也作为数据源适配为容器,因此提供了 "),t("code",[a._v("container-enum-packages")]),a._v(" 配置,用于扫描一个或多个包路径下的枚举,在应用启动后自动注册为容器:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 扫描常量包路径")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("container-constant-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.demo.constant.*\n")])])]),t("p",[a._v("关于容器部分,参见"),t("RouterLink",{attrs:{to:"/datasource/2.3.常量容器.html"}},[a._v("常量数据源容器")]),a._v("一节。")],1),a._v(" "),t("h3",{attrs:{id:"_1-3-2-2-扫描枚举容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-2-扫描枚举容器"}},[a._v("#")]),a._v(" 1.3.2.2.扫描枚举容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将枚举也作为数据源适配为容器,因此提供了 "),t("code",[a._v("container-enum-packages")]),a._v(" 配置,用于扫描一个或多个包路径下的枚举,在应用启动后自动注册为容器:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 扫描枚举包路径")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("container-enum-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.demo.constant.enums.*\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否只加载被@ContainerEnum注解的枚举")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("only-load-annotated-enum")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("关于容器部分,参见"),t("RouterLink",{attrs:{to:"/datasource/2.2.枚举容器.html"}},[a._v("枚举数据源容器")]),a._v("一节。")],1),a._v(" "),t("h3",{attrs:{id:"_1-3-2-3-扫描方法容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-3-扫描方法容器"}},[a._v("#")]),a._v(" 1.3.2.3.扫描方法容器")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 支持将被 spring 管理的 "),t("code",[a._v("bean")]),a._v(" 中带有 "),t("code",[a._v("@ContainerMethod")]),a._v(" 方法也适配为容器:")]),a._v(" "),t("div",{staticClass:"language-yaml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yaml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-container")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v("\n")])])]),t("p",[a._v("默认为 "),t("code",[a._v("true")]),a._v("。")]),a._v(" "),t("h3",{attrs:{id:"_1-3-2-4-容器缓存配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-4-容器缓存配置"}},[a._v("#")]),a._v(" 1.3.2.4.容器缓存配置")]),a._v(" "),t("p",[a._v("用户可以通过 "),t("code",[a._v("cache-containers")]),a._v(" 配置为指定的数据源容器添加缓存功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 声明哪些数据源需要包装为缓存")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("cache-containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("shared-cache")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" testContainer\n")])])]),t("p",[a._v("上述示例表示,在项目启动后,通过 "),t("code",[a._v("CacheManager")]),a._v(" 为命名空间为 "),t("code",[a._v("testContainer")]),a._v(" 的容器挂载缓存空间 "),t("code",[a._v("shared-cache")]),a._v("。")]),a._v(" "),t("h2",{attrs:{id:"_1-3-3-自动填充"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-3-自动填充"}},[a._v("#")]),a._v(" 1.3.3.自动填充")]),a._v(" "),t("p",[t("code",[a._v("crane4j")]),a._v(" 默认支持自动方法返回值与方法入参,用户也可以通过配置自定义是否关闭该功能:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" \n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否启用参数自动填充")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-argument-auto-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("false")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 是否启用返回值自动填充")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("enable-method-result-auto-operate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("false")]),a._v("\n")])])]),t("p",[a._v("关于自动填充,参见 "),t("RouterLink",{attrs:{to:"/execute/4.2.自动填充.html"}},[a._v("自动填充")]),a._v(" 一节。")],1),a._v(" "),t("h2",{attrs:{id:"_1-3-4-操作配置预解析"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-4-操作配置预解析"}},[a._v("#")]),a._v(" 1.3.4.操作配置预解析")]),a._v(" "),t("p",[a._v("由于操作配置对象 "),t("code",[a._v("BeanOperation")]),a._v(" 皆由对应的 "),t("code",[a._v("Class")]),a._v(" 解析而来,因此若解析器具备缓存功能,可以通过 "),t("code",[a._v("operate-entity-packages")]),a._v(" 配置实体类包路径,在执行器进行预解析,从而在后续调用时略过配置解析步骤,加快执行速度:")]),a._v(" "),t("div",{staticClass:"language-yml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 操作配置预解析")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("operate-entity-packages")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" cn.crane4j.springboot.config.*\n")])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/18.5103fb1f.js b/docs/assets/js/18.679a737f.js similarity index 99% rename from docs/assets/js/18.5103fb1f.js rename to docs/assets/js/18.679a737f.js index 63de075f..93e8aa77 100644 --- a/docs/assets/js/18.5103fb1f.js +++ b/docs/assets/js/18.679a737f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{290:function(_,e,v){"use strict";v.r(e);var t=v(14),a=Object(t.a)({},(function(){var _=this,e=_._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[e("h2",{attrs:{id:"_1、填充不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1、填充不生效"}},[_._v("#")]),_._v(" 1、填充不生效?")]),_._v(" "),e("ul",[e("li",[_._v("确认 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解正确配置了 "),e("code",[_._v("container")]),_._v(" 与 "),e("code",[_._v("prop")]),_._v(" 属性;")]),_._v(" "),e("li",[_._v("确认操作涉及的属性存在,且都有相应的 "),e("code",[_._v("setter")]),_._v(" 和 "),e("code",[_._v("getter")]),_._v(" 方法;")]),_._v(" "),e("li",[_._v("确认目标对象对应的 key 属性值不为空;")]),_._v(" "),e("li",[_._v("确认指定的数据源容器确实有根据 key 值列表返回非空集合;")]),_._v(" "),e("li",[_._v("确认通过 "),e("code",[_._v("BeanOperationParser")]),_._v(" 解析类后,得到的 "),e("code",[_._v("BeanOperations")]),_._v(" 中的 "),e("code",[_._v("AssembleOperation")]),_._v(" 列表中有该 key 属性对应的操作配置;")])]),_._v(" "),e("p",[_._v("仍然不行可以在 issues 中或者相关交流群中反馈。")]),_._v(" "),e("h2",{attrs:{id:"_2、如何实现嵌套填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2、如何实现嵌套填充"}},[_._v("#")]),_._v(" 2、如何实现嵌套填充?")]),_._v(" "),e("p",[_._v("在需要嵌套填充的属性上添加 "),e("code",[_._v("@Disassemble")]),_._v(" 注解即可,具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.4.拆卸嵌套对象.html"}},[_._v("拆卸嵌套对象")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_3、如何实现级联填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3、如何实现级联填充"}},[_._v("#")]),_._v(" 3、如何实现级联填充?")]),_._v(" "),e("ul",[e("li",[_._v("在需要按顺序执行的属性上添加 "),e("code",[_._v("@Order")]),_._v(" 注解(Spring 环境),或直接在 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解的 "),e("code",[_._v("sort")]),_._v(" 属性指定排序值,越小越先执行;")]),_._v(" "),e("li",[_._v("在指定操作顺序的前提下,使用有序的装配执行器 "),e("code",[_._v("OrderedBeanOperationExecutor")]),_._v(" 完成对目标的填充操作;")])]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.6.操作排序.html"}},[_._v("操作排序")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_4、如何处理一对多的情况"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_4、如何处理一对多的情况"}},[_._v("#")]),_._v(" 4、如何处理一对多的情况?")]),_._v(" "),e("p",[_._v("通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("OneToManyAssembleOperationHandler")]),_._v(" 类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中一对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_5、键字段可以是按分隔符拼接的字符串吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_5、键字段可以是按分隔符拼接的字符串吗"}},[_._v("#")]),_._v(" 5、键字段可以是按分隔符拼接的字符串吗?")]),_._v(" "),e("p",[_._v("通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("ManyToManyAssembleOperationHandler")]),_._v(" 的类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中多对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_6、键字段可以是集合或者数组吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_6、键字段可以是集合或者数组吗"}},[_._v("#")]),_._v(" 6、键字段可以是集合或者数组吗?")]),_._v(" "),e("p",[_._v("同上,通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("ManyToManyAssembleOperationHandler")]),_._v(" 的类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中多对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_7、为什么使用异步执行器的时候报错"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_7、为什么使用异步执行器的时候报错"}},[_._v("#")]),_._v(" 7、为什么使用异步执行器的时候报错?")]),_._v(" "),e("p",[_._v("默认情况下,并没有注册异步操作执行器 "),e("code",[_._v("AsyncBeanOperationExecutor")]),_._v(",用户需要自行创建后再将其注册到全局配置中。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[_._v("操作执行器")]),_._v(" 一节。")],1),_._v(" "),e("h2",{attrs:{id:"_8、怎么刷新容器的数据"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_8、怎么刷新容器的数据"}},[_._v("#")]),_._v(" 8、怎么刷新容器的数据 ?")]),_._v(" "),e("ul",[e("li",[_._v("如果容器是 "),e("code",[_._v("ConstantContainer")]),_._v(" ,直接通过 "),e("code",[_._v("get")]),_._v(" 方法获取缓存的 "),e("code",[_._v("Map")]),_._v(" 集合后直接修改即可;")]),_._v(" "),e("li",[_._v("获取 "),e("code",[_._v("Crane4jGlobalConfiguration")]),_._v(" 或 "),e("code",[_._v("ContainerManager")]),_._v(" 后,通过 "),e("code",[_._v("registerContainer")]),_._v(" 使用命名空间相同的容器对旧容器进行覆盖;")])]),_._v(" "),e("h2",{attrs:{id:"_9、怎么忽略掉某些字段不进行填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_9、怎么忽略掉某些字段不进行填充"}},[_._v("#")]),_._v(" 9、怎么忽略掉某些字段不进行填充?")]),_._v(" "),e("ul",[e("li",[_._v("使用 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解的 "),e("code",[_._v("groups")]),_._v(" 属性对指定操作进行分组;")]),_._v(" "),e("li",[_._v("在配置了分组的前提下,在使用 "),e("code",[_._v("OperateTemplate")]),_._v(" 手动填充,或通过被 "),e("code",[_._v("@AutoOperate")]),_._v(" 注解的方法进行自动填充时,指定仅执行/仅不执行特定分组的操作;")])]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.5.操作分组.html"}},[_._v("操作分组")]),_._v(" 一节。")],1),_._v(" "),e("h2",{attrs:{id:"_10、为什么-containermethod-注解不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_10、为什么-containermethod-注解不生效"}},[_._v("#")]),_._v(" 10、为什么 "),e("code",[_._v("@ContainerMethod")]),_._v(" 注解不生效?")]),_._v(" "),e("p",[_._v("如果是非 spring 环境,则需要手动的通过 "),e("code",[_._v("ContainerMethodAnnotationProcessor")]),_._v(" 扫描指定类并向全局配置注册扫描获取的方法容器。")]),_._v(" "),e("p",[_._v("如果是 spring 环境,请确保:")]),_._v(" "),e("ul",[e("li",[_._v("容器中存在 "),e("code",[_._v("BeanMethodContainerRegistrar")]),_._v(" 后处理器;")]),_._v(" "),e("li",[_._v("被注解的方法所在类被 Spring 扫描,且容器中存在对应的 bean;")]),_._v(" "),e("li",[_._v("被注解的方法所在类在 "),e("code",[_._v("BeanMethodContainerRegistrar")]),_._v(" 后处理器初始化后才加载;")])]),_._v(" "),e("h2",{attrs:{id:"_11、为什么-autooperate-注解不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_11、为什么-autooperate-注解不生效"}},[_._v("#")]),_._v(" 11、为什么 "),e("code",[_._v("@AutoOperate")]),_._v(" 注解不生效?")]),_._v(" "),e("p",[_._v("如果是非 spring 环境,则需要手动的通过 "),e("code",[_._v("MethodArgumentAutoOperateSupport")]),_._v(" 和 "),e("code",[_._v("MethodResultAutoOperateSupport")]),_._v(" 拦截方法调用。")]),_._v(" "),e("p",[_._v("如果是 spring 环境,请确保:")]),_._v(" "),e("ul",[e("li",[_._v("开启了 "),e("code",[_._v("SpringAOP")]),_._v(" 功能;")]),_._v(" "),e("li",[_._v("容器中存在 "),e("code",[_._v("MethodResultAutoOperateAdvisor")]),_._v(" 或 "),e("code",[_._v("MethodArgumentAutoOperateAdvisor")]),_._v(" 通知器;")]),_._v(" "),e("li",[_._v("被注解的方法所在类被 Spring 扫描、容器中存在对应的 bean 且被 Spring 代理;")])]),_._v(" "),e("h2",{attrs:{id:"_12、为什么引了-guava-和-hutool"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_12、为什么引了-guava-和-hutool"}},[_._v("#")]),_._v(" 12、为什么引了 guava 和 hutool ?")]),_._v(" "),e("p",[_._v("不想要重复造轮子,有些组件直接使用成熟的开源库比自己再写一套更可靠。")]),_._v(" "),e("p",[_._v("此外,"),e("code",[_._v("crane4j")]),_._v(" 仅在有限的地方使用了这些工具类库:")]),_._v(" "),e("ul",[e("li",[e("code",[_._v("guava")]),_._v(" :使用了缓存组件 "),e("code",[_._v("Cache")]),_._v(" 与用于构造 "),e("code",[_._v("WeakConcurrentMap")]),_._v(" 的 "),e("code",[_._v("MapMaker")]),_._v(";")]),_._v(" "),e("li",[e("code",[_._v("hutool")]),_._v(":使用了类型转换取组件 "),e("code",[_._v("Convert")]),_._v(",如果没用到 "),e("code",[_._v("HutoolConverterManager")]),_._v(" 可以在依赖中排除;")])]),_._v(" "),e("h2",{attrs:{id:"_13、支持-jdk9-springboot3-吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_13、支持-jdk9-springboot3-吗"}},[_._v("#")]),_._v(" 13、支持 jdk9+ / springboot3 吗?")]),_._v(" "),e("p",[_._v("在 "),e("code",[_._v("jdk11")]),_._v(" 与 "),e("code",[_._v("jdk17")]),_._v(" 和相应版本 springboot 中测试后可以正常运行。")]),_._v(" "),e("h2",{attrs:{id:"_14、容器可以做一些自定义的初始化-销毁操作吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_14、容器可以做一些自定义的初始化-销毁操作吗"}},[_._v("#")]),_._v(" 14、容器可以做一些自定义的初始化/销毁操作吗?")]),_._v(" "),e("p",[_._v("实现 "),e("code",[_._v("Container.Lifecycle")]),_._v(" 接口即可,具体参见 "),e("RouterLink",{attrs:{to:"/advance/5.3.容器的生命周期回调.html"}},[_._v("容器的生命周期回调")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_15、可以支持同时根据多个-key-字段填充数据吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_15、可以支持同时根据多个-key-字段填充数据吗"}},[_._v("#")]),_._v(" 15、可以支持同时根据多个 key 字段填充数据吗?")]),_._v(" "),e("p",[_._v("可以,不过实现方式有点特殊,具体参照 "),e("RouterLink",{attrs:{to:"/container/2.9.对象容器.html"}},[_._v("对象容器")]),_._v("。")],1)])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{289:function(_,e,v){"use strict";v.r(e);var t=v(14),a=Object(t.a)({},(function(){var _=this,e=_._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[e("h2",{attrs:{id:"_1、填充不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1、填充不生效"}},[_._v("#")]),_._v(" 1、填充不生效?")]),_._v(" "),e("ul",[e("li",[_._v("确认 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解正确配置了 "),e("code",[_._v("container")]),_._v(" 与 "),e("code",[_._v("prop")]),_._v(" 属性;")]),_._v(" "),e("li",[_._v("确认操作涉及的属性存在,且都有相应的 "),e("code",[_._v("setter")]),_._v(" 和 "),e("code",[_._v("getter")]),_._v(" 方法;")]),_._v(" "),e("li",[_._v("确认目标对象对应的 key 属性值不为空;")]),_._v(" "),e("li",[_._v("确认指定的数据源容器确实有根据 key 值列表返回非空集合;")]),_._v(" "),e("li",[_._v("确认通过 "),e("code",[_._v("BeanOperationParser")]),_._v(" 解析类后,得到的 "),e("code",[_._v("BeanOperations")]),_._v(" 中的 "),e("code",[_._v("AssembleOperation")]),_._v(" 列表中有该 key 属性对应的操作配置;")])]),_._v(" "),e("p",[_._v("仍然不行可以在 issues 中或者相关交流群中反馈。")]),_._v(" "),e("h2",{attrs:{id:"_2、如何实现嵌套填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2、如何实现嵌套填充"}},[_._v("#")]),_._v(" 2、如何实现嵌套填充?")]),_._v(" "),e("p",[_._v("在需要嵌套填充的属性上添加 "),e("code",[_._v("@Disassemble")]),_._v(" 注解即可,具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.4.拆卸嵌套对象.html"}},[_._v("拆卸嵌套对象")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_3、如何实现级联填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3、如何实现级联填充"}},[_._v("#")]),_._v(" 3、如何实现级联填充?")]),_._v(" "),e("ul",[e("li",[_._v("在需要按顺序执行的属性上添加 "),e("code",[_._v("@Order")]),_._v(" 注解(Spring 环境),或直接在 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解的 "),e("code",[_._v("sort")]),_._v(" 属性指定排序值,越小越先执行;")]),_._v(" "),e("li",[_._v("在指定操作顺序的前提下,使用有序的装配执行器 "),e("code",[_._v("OrderedBeanOperationExecutor")]),_._v(" 完成对目标的填充操作;")])]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.6.操作排序.html"}},[_._v("操作排序")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_4、如何处理一对多的情况"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_4、如何处理一对多的情况"}},[_._v("#")]),_._v(" 4、如何处理一对多的情况?")]),_._v(" "),e("p",[_._v("通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("OneToManyAssembleOperationHandler")]),_._v(" 类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中一对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_5、键字段可以是按分隔符拼接的字符串吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_5、键字段可以是按分隔符拼接的字符串吗"}},[_._v("#")]),_._v(" 5、键字段可以是按分隔符拼接的字符串吗?")]),_._v(" "),e("p",[_._v("通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("ManyToManyAssembleOperationHandler")]),_._v(" 的类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中多对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_6、键字段可以是集合或者数组吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_6、键字段可以是集合或者数组吗"}},[_._v("#")]),_._v(" 6、键字段可以是集合或者数组吗?")]),_._v(" "),e("p",[_._v("同上,通过 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解中的 "),e("code",[_._v("handler")]),_._v(" 或 "),e("code",[_._v("handlerType")]),_._v(" 属性指定装配处理器为一对多装配处理器 "),e("code",[_._v("ManyToManyAssembleOperationHandler")]),_._v(" 的类型或名称(在 spring 中即为 bean 名称)即可。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.3.指定装配处理器.html"}},[_._v("指定装配处理器")]),_._v(" 中多对多装配一节。")],1),_._v(" "),e("h2",{attrs:{id:"_7、为什么使用异步执行器的时候报错"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_7、为什么使用异步执行器的时候报错"}},[_._v("#")]),_._v(" 7、为什么使用异步执行器的时候报错?")]),_._v(" "),e("p",[_._v("默认情况下,并没有注册异步操作执行器 "),e("code",[_._v("AsyncBeanOperationExecutor")]),_._v(",用户需要自行创建后再将其注册到全局配置中。")]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[_._v("操作执行器")]),_._v(" 一节。")],1),_._v(" "),e("h2",{attrs:{id:"_8、怎么刷新容器的数据"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_8、怎么刷新容器的数据"}},[_._v("#")]),_._v(" 8、怎么刷新容器的数据 ?")]),_._v(" "),e("ul",[e("li",[_._v("如果容器是 "),e("code",[_._v("ConstantContainer")]),_._v(" ,直接通过 "),e("code",[_._v("get")]),_._v(" 方法获取缓存的 "),e("code",[_._v("Map")]),_._v(" 集合后直接修改即可;")]),_._v(" "),e("li",[_._v("获取 "),e("code",[_._v("Crane4jGlobalConfiguration")]),_._v(" 或 "),e("code",[_._v("ContainerManager")]),_._v(" 后,通过 "),e("code",[_._v("registerContainer")]),_._v(" 使用命名空间相同的容器对旧容器进行覆盖;")])]),_._v(" "),e("h2",{attrs:{id:"_9、怎么忽略掉某些字段不进行填充"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_9、怎么忽略掉某些字段不进行填充"}},[_._v("#")]),_._v(" 9、怎么忽略掉某些字段不进行填充?")]),_._v(" "),e("ul",[e("li",[_._v("使用 "),e("code",[_._v("@AssembleXXX")]),_._v(" 注解的 "),e("code",[_._v("groups")]),_._v(" 属性对指定操作进行分组;")]),_._v(" "),e("li",[_._v("在配置了分组的前提下,在使用 "),e("code",[_._v("OperateTemplate")]),_._v(" 手动填充,或通过被 "),e("code",[_._v("@AutoOperate")]),_._v(" 注解的方法进行自动填充时,指定仅执行/仅不执行特定分组的操作;")])]),_._v(" "),e("p",[_._v("具体参见 "),e("RouterLink",{attrs:{to:"/operation/3.5.操作分组.html"}},[_._v("操作分组")]),_._v(" 一节。")],1),_._v(" "),e("h2",{attrs:{id:"_10、为什么-containermethod-注解不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_10、为什么-containermethod-注解不生效"}},[_._v("#")]),_._v(" 10、为什么 "),e("code",[_._v("@ContainerMethod")]),_._v(" 注解不生效?")]),_._v(" "),e("p",[_._v("如果是非 spring 环境,则需要手动的通过 "),e("code",[_._v("ContainerMethodAnnotationProcessor")]),_._v(" 扫描指定类并向全局配置注册扫描获取的方法容器。")]),_._v(" "),e("p",[_._v("如果是 spring 环境,请确保:")]),_._v(" "),e("ul",[e("li",[_._v("容器中存在 "),e("code",[_._v("BeanMethodContainerRegistrar")]),_._v(" 后处理器;")]),_._v(" "),e("li",[_._v("被注解的方法所在类被 Spring 扫描,且容器中存在对应的 bean;")]),_._v(" "),e("li",[_._v("被注解的方法所在类在 "),e("code",[_._v("BeanMethodContainerRegistrar")]),_._v(" 后处理器初始化后才加载;")])]),_._v(" "),e("h2",{attrs:{id:"_11、为什么-autooperate-注解不生效"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_11、为什么-autooperate-注解不生效"}},[_._v("#")]),_._v(" 11、为什么 "),e("code",[_._v("@AutoOperate")]),_._v(" 注解不生效?")]),_._v(" "),e("p",[_._v("如果是非 spring 环境,则需要手动的通过 "),e("code",[_._v("MethodArgumentAutoOperateSupport")]),_._v(" 和 "),e("code",[_._v("MethodResultAutoOperateSupport")]),_._v(" 拦截方法调用。")]),_._v(" "),e("p",[_._v("如果是 spring 环境,请确保:")]),_._v(" "),e("ul",[e("li",[_._v("开启了 "),e("code",[_._v("SpringAOP")]),_._v(" 功能;")]),_._v(" "),e("li",[_._v("容器中存在 "),e("code",[_._v("MethodResultAutoOperateAdvisor")]),_._v(" 或 "),e("code",[_._v("MethodArgumentAutoOperateAdvisor")]),_._v(" 通知器;")]),_._v(" "),e("li",[_._v("被注解的方法所在类被 Spring 扫描、容器中存在对应的 bean 且被 Spring 代理;")])]),_._v(" "),e("h2",{attrs:{id:"_12、为什么引了-guava-和-hutool"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_12、为什么引了-guava-和-hutool"}},[_._v("#")]),_._v(" 12、为什么引了 guava 和 hutool ?")]),_._v(" "),e("p",[_._v("不想要重复造轮子,有些组件直接使用成熟的开源库比自己再写一套更可靠。")]),_._v(" "),e("p",[_._v("此外,"),e("code",[_._v("crane4j")]),_._v(" 仅在有限的地方使用了这些工具类库:")]),_._v(" "),e("ul",[e("li",[e("code",[_._v("guava")]),_._v(" :使用了缓存组件 "),e("code",[_._v("Cache")]),_._v(" 与用于构造 "),e("code",[_._v("WeakConcurrentMap")]),_._v(" 的 "),e("code",[_._v("MapMaker")]),_._v(";")]),_._v(" "),e("li",[e("code",[_._v("hutool")]),_._v(":使用了类型转换取组件 "),e("code",[_._v("Convert")]),_._v(",如果没用到 "),e("code",[_._v("HutoolConverterManager")]),_._v(" 可以在依赖中排除;")])]),_._v(" "),e("h2",{attrs:{id:"_13、支持-jdk9-springboot3-吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_13、支持-jdk9-springboot3-吗"}},[_._v("#")]),_._v(" 13、支持 jdk9+ / springboot3 吗?")]),_._v(" "),e("p",[_._v("在 "),e("code",[_._v("jdk11")]),_._v(" 与 "),e("code",[_._v("jdk17")]),_._v(" 和相应版本 springboot 中测试后可以正常运行。")]),_._v(" "),e("h2",{attrs:{id:"_14、容器可以做一些自定义的初始化-销毁操作吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_14、容器可以做一些自定义的初始化-销毁操作吗"}},[_._v("#")]),_._v(" 14、容器可以做一些自定义的初始化/销毁操作吗?")]),_._v(" "),e("p",[_._v("实现 "),e("code",[_._v("Container.Lifecycle")]),_._v(" 接口即可,具体参见 "),e("RouterLink",{attrs:{to:"/advance/5.3.容器的生命周期回调.html"}},[_._v("容器的生命周期回调")]),_._v("。")],1),_._v(" "),e("h2",{attrs:{id:"_15、可以支持同时根据多个-key-字段填充数据吗"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_15、可以支持同时根据多个-key-字段填充数据吗"}},[_._v("#")]),_._v(" 15、可以支持同时根据多个 key 字段填充数据吗?")]),_._v(" "),e("p",[_._v("可以,不过实现方式有点特殊,具体参照 "),e("RouterLink",{attrs:{to:"/container/2.9.对象容器.html"}},[_._v("对象容器")]),_._v("。")],1)])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/19.c7fed70c.js b/docs/assets/js/19.24911a7e.js similarity index 91% rename from docs/assets/js/19.c7fed70c.js rename to docs/assets/js/19.24911a7e.js index 19d4b41b..dc4507b8 100644 --- a/docs/assets/js/19.c7fed70c.js +++ b/docs/assets/js/19.24911a7e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{292:function(t,s,n){"use strict";n.r(s);var r=n(14),i=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"快速开始"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#快速开始"}},[this._v("#")]),this._v(" 快速开始")]),this._v(" "),t("p",[t("code",[this._v("crane4j")]),this._v(" 可以非常丝滑的接入 springboot 或 spring 项目。如有必要,也可以运行在非 spring 环境,这种情况下用户依然可以使用大部分功能,不过由于缺少 IOC 与自动装配支持,有一些组件需要用户自行启用。")])])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{291:function(t,s,n){"use strict";n.r(s);var r=n(14),i=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"快速开始"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#快速开始"}},[this._v("#")]),this._v(" 快速开始")]),this._v(" "),t("p",[t("code",[this._v("crane4j")]),this._v(" 可以非常丝滑的接入 springboot 或 spring 项目。如有必要,也可以运行在非 spring 环境,这种情况下用户依然可以使用大部分功能,不过由于缺少 IOC 与自动装配支持,有一些组件需要用户自行启用。")])])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/20.bd9631f8.js b/docs/assets/js/20.962b0a21.js similarity index 99% rename from docs/assets/js/20.bd9631f8.js rename to docs/assets/js/20.962b0a21.js index d3128143..51fba0a0 100644 --- a/docs/assets/js/20.bd9631f8.js +++ b/docs/assets/js/20.962b0a21.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{299:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),s("h3",{attrs:{id:"引入依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#引入依赖"}},[t._v("#")]),t._v(" 引入依赖")]),t._v(" "),s("p",[t._v("在非 spring 环境中,引入 "),s("code",[t._v("crane4j-core")]),t._v(" 模块即可:")]),t._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("cn.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("crane4j-core"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("当前最新版本为 "),s("img",{attrs:{src:"https://img.shields.io/github/v/release/Createsequence/crane4j?include_prereleases",alt:"maven-central"}})])]),t._v(" "),s("h3",{attrs:{id:"全局配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#全局配置"}},[t._v("#")]),t._v(" 全局配置")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 类似于其他框架,也提供了一个全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(",类似于 MyBatis 的 "),s("code",[t._v("Configuration")]),t._v(",用于管理 "),s("code",[t._v("crane4j")]),t._v(" 的各种组件。在非 Spring 环境下,由于没有自动装配的功能,推荐使用 "),s("code",[t._v("SimpleCrane4jGlobalConfiguration.create")]),t._v(" 工厂方法以默认配置创建一个实例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建一个默认配置类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("用户需要自行保存 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例,通常它应该是全局单例的。")]),t._v(" "),s("h3",{attrs:{id:"启用填充工具"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用填充工具"}},[t._v("#")]),t._v(" 启用填充工具")]),t._v(" "),s("p",[t._v("获得了 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例后,用户可以创建一个 "),s("code",[t._v("OperateTemplate")]),t._v(" 工具类,它可以方便地完成填充操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 基于默认的配置解析器与执行器创建 OperateTemplate")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" template "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBeanOperationsParser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getTypeResolver")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("与 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 一样,"),s("code",[t._v("OperateTemplate")]),t._v(" 也应该是单例的。")]),t._v(" "),s("h3",{attrs:{id:"启用扩展功能"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用扩展功能"}},[t._v("#")]),t._v(" 启用扩展功能")]),t._v(" "),s("p",[t._v("在非 Spring 环境下,由于缺少自动化的后处理和 AOP 等能力,因此 "),s("code",[t._v("crane4j")]),t._v(" 的一些扩展功能需要用户自行启用:")]),t._v(" "),s("ol",[s("li",[t._v("自动填充方法的入参:"),s("code",[t._v("MethodArgumentAutoOperateSupport")]),t._v(";")]),t._v(" "),s("li",[t._v("自动填充方法的返回值:"),s("code",[t._v("MethodResultAutoOperateSupport")]),t._v(";")]),t._v(" "),s("li",[t._v("方法数据源容器适配:"),s("code",[t._v("ContainerMethodAnnotationProcessor")]),t._v(";")]),t._v(" "),s("li",[t._v("容器的缓存功能:"),s("code",[t._v("DefaultCacheableContainerProcessor")]),t._v(";")])]),t._v(" "),s("p",[t._v("这些扩展功能需要用户根据需求进行配置和启用,如有疑问,可以参考文档或测试用例,也可以直接咨询作者。")]),t._v(" "),s("h2",{attrs:{id:"配置数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置数据源"}},[t._v("#")]),t._v(" 配置数据源")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,一个数据源对应一个"),s("strong",[t._v("数据源容器")]),t._v(",因此在进行填充操作之前,需要先准备好相应的数据源容器。")]),t._v(" "),s("p",[t._v("下面是一个简单的示例,配置了一个命名空间为 "),s("code",[t._v("gender")]),t._v(" 的数据源容器,根据 0 或 1 返回对应的性别名称:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注册性别信息数据源")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" sources "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" genderContainer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("接下来,我们将该容器注册到之前创建的全局配置类 "),s("code",[t._v("SimpleCrane4jGlobalConfiguration")]),t._v(" 中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 前文创建的 SimpleCrane4jGlobalConfiguration 实例")]),t._v("\nconfiguration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genderContainer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("注册数据源的步骤也可以放在 "),s("code",[t._v("ApplicationRunner")]),t._v(" 或者用 "),s("code",[t._v("@PostConstruct")]),t._v(" 注解的回调方法中执行。")]),t._v(" "),s("li",[t._v("除了处理简单的本地缓存外,"),s("code",[t._v("crane4j")]),t._v(" 也支持创建其他类型的数据源容器,具体内容可以参考后文关于数据源容器的部分")])])]),t._v(" "),s("h2",{attrs:{id:"配置装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置装配操作"}},[t._v("#")]),t._v(" 配置装配操作")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,"),s("strong",[t._v("装配操作")]),t._v("是指对某个对象的填充行为。我们可以通过在类或属性上添加注解来配置装配操作。")]),t._v(" "),s("p",[t._v("例如,在"),s("code",[t._v("Student")]),t._v("类中声明了一个装配操作:")]),t._v(" "),s("ul",[s("li",[t._v("该操作基于"),s("code",[t._v("sex")]),t._v("字段的值来执行,即根据"),s("code",[t._v("sex")]),t._v("字段的值查找关联数据。")]),t._v(" "),s("li",[t._v("从命名空间为"),s("code",[t._v("gender")]),t._v("的数据源容器获取关联数据。")]),t._v(" "),s("li",[t._v("将获取的关联数据直接赋值给"),s("code",[t._v("sexName")]),t._v("引用字段。")])]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 lombok 生成 get 方法和构造器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Setter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示根据"),s("code",[t._v("sex")]),t._v("字段从"),s("code",[t._v("gender")]),t._v("数据源容器中查找对应的男/女名称,并映射到"),s("code",[t._v("sexName")]),t._v("字段上。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("@Assemble")]),t._v(" 注解用于声明一次填充操作,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.1.声明装配操作.html"}},[t._v("装配操作")]),t._v("一节;")],1),t._v(" "),s("li",[s("code",[t._v("@Mapping")]),t._v(" 用于指明数据源对象上的字段要如何映射到待处理对象的字段上,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.4.配置字段映射.html"}},[t._v("字段映射")]),t._v("一节;")],1)])]),t._v(" "),s("h2",{attrs:{id:"执行装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行装配操作"}},[t._v("#")]),t._v(" 执行装配操作")]),t._v(" "),s("p",[t._v("在项目启动后,用户可以直接通过上文创建的填充工具类 "),s("code",[t._v("OperateTemplate")]),t._v(" 去填充我们已经配置过的对象:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 用户自己保存的 OperateTemplate 实例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在执行后,"),s("code",[t._v("students")]),t._v(" 中对象的 "),s("code",[t._v("sexName")]),t._v(" 将根据 "),s("code",[t._v("sex")]),t._v(" 字段的值被填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"执行嵌套填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行嵌套填充"}},[t._v("#")]),t._v(" 执行嵌套填充")]),t._v(" "),s("p",[t._v("当我们需要填充嵌套对象时,除了为嵌套字段声明装配操作外,还需要为需要填充的嵌套字段声明"),s("strong",[t._v("拆卸操作")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,"),s("code",[t._v("Student")]),t._v("对象中嵌套了一个需要填充的"),s("code",[t._v("StudentClass")]),t._v("对象。该对象需要通过 id 从命名空间为 "),s("code",[t._v("student-class")]),t._v(" 的数据源容器获取数据源对象的 "),s("code",[t._v("name")]),t._v(" 属性,并将其填充到自己的 "),s("code",[t._v("name")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("除了为 "),s("code",[t._v("StudentClass")]),t._v(" 类声明装配操作外,我们还需要在 "),s("code",[t._v("Student")]),t._v(" 的 "),s("code",[t._v("studentClass")]),t._v(" 属性上通过注解声明一个拆卸操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个拆卸操作,拆卸后需要填充的对象类型为 StudentClass")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 字段类型可以是单个对象,数组或者 Collection 集合")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Disassemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" studentClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Props")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示,在执行装配操作之前,我们需要先将 "),s("code",[t._v("Student")]),t._v(" 中的 "),s("code",[t._v("StudentClass")]),t._v(" 取出并摊平,然后再完成所有待处理的 "),s("code",[t._v("Student")]),t._v(" 和 "),s("code",[t._v("StudentClass")]),t._v(" 对象的装配操作。")]),t._v(" "),s("p",[t._v("我们依然在项目启动后执行下述代码:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 用户自己保存的 OperateTemplate 实例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("执行后,"),s("code",[t._v("students")]),t._v(" 中的 "),s("code",[t._v("Student")]),t._v(" 对象及嵌套的 "),s("code",[t._v("StudentClass")]),t._v(" 对象将会被填充:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年1班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年2班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{303:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),s("h3",{attrs:{id:"引入依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#引入依赖"}},[t._v("#")]),t._v(" 引入依赖")]),t._v(" "),s("p",[t._v("在非 spring 环境中,引入 "),s("code",[t._v("crane4j-core")]),t._v(" 模块即可:")]),t._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("cn.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("crane4j-core"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("当前最新版本为 "),s("img",{attrs:{src:"https://img.shields.io/github/v/release/Createsequence/crane4j?include_prereleases",alt:"maven-central"}})])]),t._v(" "),s("h3",{attrs:{id:"全局配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#全局配置"}},[t._v("#")]),t._v(" 全局配置")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 类似于其他框架,也提供了一个全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(",类似于 MyBatis 的 "),s("code",[t._v("Configuration")]),t._v(",用于管理 "),s("code",[t._v("crane4j")]),t._v(" 的各种组件。在非 Spring 环境下,由于没有自动装配的功能,推荐使用 "),s("code",[t._v("SimpleCrane4jGlobalConfiguration.create")]),t._v(" 工厂方法以默认配置创建一个实例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建一个默认配置类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("用户需要自行保存 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例,通常它应该是全局单例的。")]),t._v(" "),s("h3",{attrs:{id:"启用填充工具"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用填充工具"}},[t._v("#")]),t._v(" 启用填充工具")]),t._v(" "),s("p",[t._v("获得了 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例后,用户可以创建一个 "),s("code",[t._v("OperateTemplate")]),t._v(" 工具类,它可以方便地完成填充操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 基于默认的配置解析器与执行器创建 OperateTemplate")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" template "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBeanOperationsParser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getTypeResolver")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("与 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 一样,"),s("code",[t._v("OperateTemplate")]),t._v(" 也应该是单例的。")]),t._v(" "),s("h3",{attrs:{id:"启用扩展功能"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用扩展功能"}},[t._v("#")]),t._v(" 启用扩展功能")]),t._v(" "),s("p",[t._v("在非 Spring 环境下,由于缺少自动化的后处理和 AOP 等能力,因此 "),s("code",[t._v("crane4j")]),t._v(" 的一些扩展功能需要用户自行启用:")]),t._v(" "),s("ol",[s("li",[t._v("自动填充方法的入参:"),s("code",[t._v("MethodArgumentAutoOperateSupport")]),t._v(";")]),t._v(" "),s("li",[t._v("自动填充方法的返回值:"),s("code",[t._v("MethodResultAutoOperateSupport")]),t._v(";")]),t._v(" "),s("li",[t._v("方法数据源容器适配:"),s("code",[t._v("ContainerMethodAnnotationProcessor")]),t._v(";")]),t._v(" "),s("li",[t._v("容器的缓存功能:"),s("code",[t._v("DefaultCacheableContainerProcessor")]),t._v(";")])]),t._v(" "),s("p",[t._v("这些扩展功能需要用户根据需求进行配置和启用,如有疑问,可以参考文档或测试用例,也可以直接咨询作者。")]),t._v(" "),s("h2",{attrs:{id:"配置数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置数据源"}},[t._v("#")]),t._v(" 配置数据源")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,一个数据源对应一个"),s("strong",[t._v("数据源容器")]),t._v(",因此在进行填充操作之前,需要先准备好相应的数据源容器。")]),t._v(" "),s("p",[t._v("下面是一个简单的示例,配置了一个命名空间为 "),s("code",[t._v("gender")]),t._v(" 的数据源容器,根据 0 或 1 返回对应的性别名称:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注册性别信息数据源")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" sources "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" genderContainer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("接下来,我们将该容器注册到之前创建的全局配置类 "),s("code",[t._v("SimpleCrane4jGlobalConfiguration")]),t._v(" 中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 前文创建的 SimpleCrane4jGlobalConfiguration 实例")]),t._v("\nconfiguration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genderContainer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("注册数据源的步骤也可以放在 "),s("code",[t._v("ApplicationRunner")]),t._v(" 或者用 "),s("code",[t._v("@PostConstruct")]),t._v(" 注解的回调方法中执行。")]),t._v(" "),s("li",[t._v("除了处理简单的本地缓存外,"),s("code",[t._v("crane4j")]),t._v(" 也支持创建其他类型的数据源容器,具体内容可以参考后文关于数据源容器的部分")])])]),t._v(" "),s("h2",{attrs:{id:"配置装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置装配操作"}},[t._v("#")]),t._v(" 配置装配操作")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,"),s("strong",[t._v("装配操作")]),t._v("是指对某个对象的填充行为。我们可以通过在类或属性上添加注解来配置装配操作。")]),t._v(" "),s("p",[t._v("例如,在"),s("code",[t._v("Student")]),t._v("类中声明了一个装配操作:")]),t._v(" "),s("ul",[s("li",[t._v("该操作基于"),s("code",[t._v("sex")]),t._v("字段的值来执行,即根据"),s("code",[t._v("sex")]),t._v("字段的值查找关联数据。")]),t._v(" "),s("li",[t._v("从命名空间为"),s("code",[t._v("gender")]),t._v("的数据源容器获取关联数据。")]),t._v(" "),s("li",[t._v("将获取的关联数据直接赋值给"),s("code",[t._v("sexName")]),t._v("引用字段。")])]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 lombok 生成 get 方法和构造器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Setter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示根据"),s("code",[t._v("sex")]),t._v("字段从"),s("code",[t._v("gender")]),t._v("数据源容器中查找对应的男/女名称,并映射到"),s("code",[t._v("sexName")]),t._v("字段上。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("@Assemble")]),t._v(" 注解用于声明一次填充操作,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.1.声明装配操作.html"}},[t._v("装配操作")]),t._v("一节;")],1),t._v(" "),s("li",[s("code",[t._v("@Mapping")]),t._v(" 用于指明数据源对象上的字段要如何映射到待处理对象的字段上,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.4.配置字段映射.html"}},[t._v("字段映射")]),t._v("一节;")],1)])]),t._v(" "),s("h2",{attrs:{id:"执行装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行装配操作"}},[t._v("#")]),t._v(" 执行装配操作")]),t._v(" "),s("p",[t._v("在项目启动后,用户可以直接通过上文创建的填充工具类 "),s("code",[t._v("OperateTemplate")]),t._v(" 去填充我们已经配置过的对象:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 用户自己保存的 OperateTemplate 实例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在执行后,"),s("code",[t._v("students")]),t._v(" 中对象的 "),s("code",[t._v("sexName")]),t._v(" 将根据 "),s("code",[t._v("sex")]),t._v(" 字段的值被填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"执行嵌套填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行嵌套填充"}},[t._v("#")]),t._v(" 执行嵌套填充")]),t._v(" "),s("p",[t._v("当我们需要填充嵌套对象时,除了为嵌套字段声明装配操作外,还需要为需要填充的嵌套字段声明"),s("strong",[t._v("拆卸操作")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,"),s("code",[t._v("Student")]),t._v("对象中嵌套了一个需要填充的"),s("code",[t._v("StudentClass")]),t._v("对象。该对象需要通过 id 从命名空间为 "),s("code",[t._v("student-class")]),t._v(" 的数据源容器获取数据源对象的 "),s("code",[t._v("name")]),t._v(" 属性,并将其填充到自己的 "),s("code",[t._v("name")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("除了为 "),s("code",[t._v("StudentClass")]),t._v(" 类声明装配操作外,我们还需要在 "),s("code",[t._v("Student")]),t._v(" 的 "),s("code",[t._v("studentClass")]),t._v(" 属性上通过注解声明一个拆卸操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个拆卸操作,拆卸后需要填充的对象类型为 StudentClass")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 字段类型可以是单个对象,数组或者 Collection 集合")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Disassemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" studentClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Props")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示,在执行装配操作之前,我们需要先将 "),s("code",[t._v("Student")]),t._v(" 中的 "),s("code",[t._v("StudentClass")]),t._v(" 取出并摊平,然后再完成所有待处理的 "),s("code",[t._v("Student")]),t._v(" 和 "),s("code",[t._v("StudentClass")]),t._v(" 对象的装配操作。")]),t._v(" "),s("p",[t._v("我们依然在项目启动后执行下述代码:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 用户自己保存的 OperateTemplate 实例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("执行后,"),s("code",[t._v("students")]),t._v(" 中的 "),s("code",[t._v("Student")]),t._v(" 对象及嵌套的 "),s("code",[t._v("StudentClass")]),t._v(" 对象将会被填充:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年1班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年2班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/21.0edf4fa9.js b/docs/assets/js/21.e42ba737.js similarity index 99% rename from docs/assets/js/21.0edf4fa9.js rename to docs/assets/js/21.e42ba737.js index 2c7b52ad..71bb9c76 100644 --- a/docs/assets/js/21.0edf4fa9.js +++ b/docs/assets/js/21.e42ba737.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{294:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),s("h3",{attrs:{id:"引入依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#引入依赖"}},[t._v("#")]),t._v(" 引入依赖")]),t._v(" "),s("p",[t._v("在 Spring 项目中,请引入 "),s("code",[t._v("crane4j-spring-extension")]),t._v(" 依赖:")]),t._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("cn.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("crane4j-extension-spring"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v("并请确保已经引入 "),s("code",[t._v("spring-context")]),t._v("、"),s("code",[t._v("aspectjweaver")]),t._v(" 依赖。")]),t._v(" "),s("blockquote",[s("p",[t._v("当前最新版本为 "),s("img",{attrs:{src:"https://img.shields.io/github/v/release/Createsequence/crane4j?include_prereleases",alt:"maven-central"}})])]),t._v(" "),s("h3",{attrs:{id:"启用配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用配置"}},[t._v("#")]),t._v(" 启用配置")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 已经准备好了默认的配置类 "),s("code",[t._v("DefaultCrane4jSpringConfiguration")]),t._v(",用户仅需在自己的项目通过下述任意方式将其纳入 Spring 容器管理即可:")]),t._v(" "),s("ul",[s("li",[t._v("在 "),s("code",[t._v("xml")]),t._v(" 或者配置类中手动创建 "),s("code",[t._v("DefaultCrane4jSpringConfiguration")]),t._v(" 实例;")]),t._v(" "),s("li",[t._v("在任意配置类上通过 "),s("code",[t._v("@Import")]),t._v(" 注解引入 "),s("code",[t._v("DefaultCrane4jSpringConfiguration.class")]),t._v(";")])]),t._v(" "),s("p",[t._v("确保在项目启动后,上述配置类中配置的组件都已注册到 spring 上下文中。")]),t._v(" "),s("h2",{attrs:{id:"配置数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置数据源"}},[t._v("#")]),t._v(" 配置数据源")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,一个数据源对应一个"),s("strong",[t._v("数据源容器")]),t._v(",因此在进行填充操作之前,需要先准备好相应的数据源容器。")]),t._v(" "),s("p",[t._v("下面是一个简单的示例,配置了一个命名空间为 "),s("code",[t._v("gender")]),t._v(" 的数据源容器,根据 0 或 1 返回对应的性别名称:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注册性别信息数据源")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" sources "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" genderContainer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("接着,我们将其注册从 spring 容器获得的全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" context "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncontext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genderContainer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("注册数据源的步骤我们也可以放到 "),s("code",[t._v("@PostConstruct")]),t._v(" 注解方法或者其他声明周期回调中;")]),t._v(" "),s("li",[t._v("处简单的本地缓存外,"),s("code",[t._v("crane4j")]),t._v(" 还支持创建其他种类的数据源容器,具体参见后文数据源容器部分内容;")])])]),t._v(" "),s("h2",{attrs:{id:"配置装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置装配操作"}},[t._v("#")]),t._v(" 配置装配操作")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,"),s("strong",[t._v("装配操作")]),t._v("是指对某个对象的填充行为。我们可以通过在类或属性上添加注解来配置装配操作。")]),t._v(" "),s("p",[t._v("例如,在"),s("code",[t._v("Student")]),t._v("类中声明了一个装配操作:")]),t._v(" "),s("ul",[s("li",[t._v("该操作基于"),s("code",[t._v("sex")]),t._v("字段的值来执行,即根据"),s("code",[t._v("sex")]),t._v("字段的值查找关联数据。")]),t._v(" "),s("li",[t._v("从命名空间为"),s("code",[t._v("gender")]),t._v("的数据源容器获取关联数据。")]),t._v(" "),s("li",[t._v("将获取的关联数据直接赋值给"),s("code",[t._v("sexName")]),t._v("引用字段。")])]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 lombok 生成 get 方法和构造器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Setter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示根据"),s("code",[t._v("sex")]),t._v("字段从"),s("code",[t._v("gender")]),t._v("数据源容器中查找对应的男/女名称,并映射到"),s("code",[t._v("sexName")]),t._v("字段上。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("@Assemble")]),t._v(" 注解用于声明一次填充操作,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.1.声明装配操作.html"}},[t._v("装配操作")]),t._v("一节;")],1),t._v(" "),s("li",[s("code",[t._v("@Mapping")]),t._v(" 用于指明数据源对象上的字段要如何映射到待处理对象的字段上,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.4.配置字段映射.html"}},[t._v("字段映射")]),t._v("一节;")],1)])]),t._v(" "),s("h2",{attrs:{id:"执行装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行装配操作"}},[t._v("#")]),t._v(" 执行装配操作")]),t._v(" "),s("p",[t._v("在项目启动后,我们可以从 spring 容器中获取填充工具类 "),s("code",[t._v("OperateTemplate")]),t._v(" 去填充我们已经配置过的对象:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在执行后,"),s("code",[t._v("students")]),t._v(" 中对象的 "),s("code",[t._v("sexName")]),t._v(" 将根据 "),s("code",[t._v("sex")]),t._v(" 字段的值被填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"执行嵌套填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行嵌套填充"}},[t._v("#")]),t._v(" 执行嵌套填充")]),t._v(" "),s("p",[t._v("当我们需要填充嵌套对象时,除了为嵌套字段声明装配操作外,还需要为需要填充的嵌套字段声明"),s("strong",[t._v("拆卸操作")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,"),s("code",[t._v("Student")]),t._v("对象中嵌套了一个需要填充的"),s("code",[t._v("StudentClass")]),t._v("对象。该对象需要通过 id 从命名空间为 "),s("code",[t._v("student-class")]),t._v(" 的数据源容器获取数据源对象的 "),s("code",[t._v("name")]),t._v(" 属性,并将其填充到自己的 "),s("code",[t._v("name")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("除了为 "),s("code",[t._v("StudentClass")]),t._v(" 类声明装配操作外,我们还需要在 "),s("code",[t._v("Student")]),t._v(" 的 "),s("code",[t._v("studentClass")]),t._v(" 属性上通过注解声明一个拆卸操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个拆卸操作,拆卸后需要填充的对象类型为 StudentClass")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 字段类型可以是单个对象,数组或者 Collection 集合")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Disassemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" studentClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Props")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示,在执行装配操作之前,我们需要先将 "),s("code",[t._v("Student")]),t._v(" 中的 "),s("code",[t._v("StudentClass")]),t._v(" 取出并摊平,然后再完成所有待处理的 "),s("code",[t._v("Student")]),t._v(" 和 "),s("code",[t._v("StudentClass")]),t._v(" 对象的装配操作。")]),t._v(" "),s("p",[t._v("我们依然在项目启动后执行下述代码:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("执行后,"),s("code",[t._v("students")]),t._v(" 中的 "),s("code",[t._v("Student")]),t._v(" 对象及嵌套的 "),s("code",[t._v("StudentClass")]),t._v(" 对象将会被填充:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年1班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年2班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{308:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),s("h3",{attrs:{id:"引入依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#引入依赖"}},[t._v("#")]),t._v(" 引入依赖")]),t._v(" "),s("p",[t._v("在 Spring 项目中,请引入 "),s("code",[t._v("crane4j-spring-extension")]),t._v(" 依赖:")]),t._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("cn.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("crane4j-extension-spring"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v("并请确保已经引入 "),s("code",[t._v("spring-context")]),t._v("、"),s("code",[t._v("aspectjweaver")]),t._v(" 依赖。")]),t._v(" "),s("blockquote",[s("p",[t._v("当前最新版本为 "),s("img",{attrs:{src:"https://img.shields.io/github/v/release/Createsequence/crane4j?include_prereleases",alt:"maven-central"}})])]),t._v(" "),s("h3",{attrs:{id:"启用配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#启用配置"}},[t._v("#")]),t._v(" 启用配置")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 已经准备好了默认的配置类 "),s("code",[t._v("DefaultCrane4jSpringConfiguration")]),t._v(",用户仅需在自己的项目通过下述任意方式将其纳入 Spring 容器管理即可:")]),t._v(" "),s("ul",[s("li",[t._v("在 "),s("code",[t._v("xml")]),t._v(" 或者配置类中手动创建 "),s("code",[t._v("DefaultCrane4jSpringConfiguration")]),t._v(" 实例;")]),t._v(" "),s("li",[t._v("在任意配置类上通过 "),s("code",[t._v("@Import")]),t._v(" 注解引入 "),s("code",[t._v("DefaultCrane4jSpringConfiguration.class")]),t._v(";")])]),t._v(" "),s("p",[t._v("确保在项目启动后,上述配置类中配置的组件都已注册到 spring 上下文中。")]),t._v(" "),s("h2",{attrs:{id:"配置数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置数据源"}},[t._v("#")]),t._v(" 配置数据源")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,一个数据源对应一个"),s("strong",[t._v("数据源容器")]),t._v(",因此在进行填充操作之前,需要先准备好相应的数据源容器。")]),t._v(" "),s("p",[t._v("下面是一个简单的示例,配置了一个命名空间为 "),s("code",[t._v("gender")]),t._v(" 的数据源容器,根据 0 或 1 返回对应的性别名称:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注册性别信息数据源")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" sources "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" genderContainer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sources"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("接着,我们将其注册从 spring 容器获得的全局配置类 "),s("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" context "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncontext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genderContainer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("注册数据源的步骤我们也可以放到 "),s("code",[t._v("@PostConstruct")]),t._v(" 注解方法或者其他声明周期回调中;")]),t._v(" "),s("li",[t._v("处简单的本地缓存外,"),s("code",[t._v("crane4j")]),t._v(" 还支持创建其他种类的数据源容器,具体参见后文数据源容器部分内容;")])])]),t._v(" "),s("h2",{attrs:{id:"配置装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置装配操作"}},[t._v("#")]),t._v(" 配置装配操作")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,"),s("strong",[t._v("装配操作")]),t._v("是指对某个对象的填充行为。我们可以通过在类或属性上添加注解来配置装配操作。")]),t._v(" "),s("p",[t._v("例如,在"),s("code",[t._v("Student")]),t._v("类中声明了一个装配操作:")]),t._v(" "),s("ul",[s("li",[t._v("该操作基于"),s("code",[t._v("sex")]),t._v("字段的值来执行,即根据"),s("code",[t._v("sex")]),t._v("字段的值查找关联数据。")]),t._v(" "),s("li",[t._v("从命名空间为"),s("code",[t._v("gender")]),t._v("的数据源容器获取关联数据。")]),t._v(" "),s("li",[t._v("将获取的关联数据直接赋值给"),s("code",[t._v("sexName")]),t._v("引用字段。")])]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 lombok 生成 get 方法和构造器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Setter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示根据"),s("code",[t._v("sex")]),t._v("字段从"),s("code",[t._v("gender")]),t._v("数据源容器中查找对应的男/女名称,并映射到"),s("code",[t._v("sexName")]),t._v("字段上。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("@Assemble")]),t._v(" 注解用于声明一次填充操作,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.1.声明装配操作.html"}},[t._v("装配操作")]),t._v("一节;")],1),t._v(" "),s("li",[s("code",[t._v("@Mapping")]),t._v(" 用于指明数据源对象上的字段要如何映射到待处理对象的字段上,具体参见后文"),s("RouterLink",{attrs:{to:"/basic/operation/3.4.配置字段映射.html"}},[t._v("字段映射")]),t._v("一节;")],1)])]),t._v(" "),s("h2",{attrs:{id:"执行装配操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行装配操作"}},[t._v("#")]),t._v(" 执行装配操作")]),t._v(" "),s("p",[t._v("在项目启动后,我们可以从 spring 容器中获取填充工具类 "),s("code",[t._v("OperateTemplate")]),t._v(" 去填充我们已经配置过的对象:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在执行后,"),s("code",[t._v("students")]),t._v(" 中对象的 "),s("code",[t._v("sexName")]),t._v(" 将根据 "),s("code",[t._v("sex")]),t._v(" 字段的值被填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"执行嵌套填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行嵌套填充"}},[t._v("#")]),t._v(" 执行嵌套填充")]),t._v(" "),s("p",[t._v("当我们需要填充嵌套对象时,除了为嵌套字段声明装配操作外,还需要为需要填充的嵌套字段声明"),s("strong",[t._v("拆卸操作")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,"),s("code",[t._v("Student")]),t._v("对象中嵌套了一个需要填充的"),s("code",[t._v("StudentClass")]),t._v("对象。该对象需要通过 id 从命名空间为 "),s("code",[t._v("student-class")]),t._v(" 的数据源容器获取数据源对象的 "),s("code",[t._v("name")]),t._v(" 属性,并将其填充到自己的 "),s("code",[t._v("name")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("除了为 "),s("code",[t._v("StudentClass")]),t._v(" 类声明装配操作外,我们还需要在 "),s("code",[t._v("Student")]),t._v(" 的 "),s("code",[t._v("studentClass")]),t._v(" 属性上通过注解声明一个拆卸操作:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定使用的命名空间为 gender 的数据源容器")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将根据 sex 取得值映射到 sexName 上")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sexName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个拆卸操作,拆卸后需要填充的对象类型为 StudentClass")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 字段类型可以是单个对象,数组或者 Collection 集合")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Disassemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" studentClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Props")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以上配置表示,在执行装配操作之前,我们需要先将 "),s("code",[t._v("Student")]),t._v(" 中的 "),s("code",[t._v("StudentClass")]),t._v(" 取出并摊平,然后再完成所有待处理的 "),s("code",[t._v("Student")]),t._v(" 和 "),s("code",[t._v("StudentClass")]),t._v(" 对象的装配操作。")]),t._v(" "),s("p",[t._v("我们依然在项目启动后执行下述代码:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" students "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("students"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("执行后,"),s("code",[t._v("students")]),t._v(" 中的 "),s("code",[t._v("Student")]),t._v(" 对象及嵌套的 "),s("code",[t._v("StudentClass")]),t._v(" 对象将会被填充:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小红"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年1班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"小明"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sex"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"sexName"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"studentClass"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"一年2班"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/24.9ba4a3fd.js b/docs/assets/js/24.790cb885.js similarity index 98% rename from docs/assets/js/24.9ba4a3fd.js rename to docs/assets/js/24.790cb885.js index 188f3f77..24d4dc7a 100644 --- a/docs/assets/js/24.9ba4a3fd.js +++ b/docs/assets/js/24.790cb885.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{295:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"本地缓存容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#本地缓存容器"}},[t._v("#")]),t._v(" 本地缓存容器")]),t._v(" "),s("p",[t._v("本地缓存可以简单地理解为以 "),s("code",[t._v("Map")]),t._v(" 或其他数据结构形式保存在本地 JVM 缓存中的数据,常见的例子包括系统启动后加载的配置项或字典项。")]),t._v(" "),s("p",[t._v("通过 "),s("code",[t._v("Containers")]),t._v(" 的 "),s("code",[t._v("forMap")]),t._v(" 工厂方法,我们可以快速配置一个数据源容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("当输入一个键值作为 key 时,该容器将从 "),s("code",[t._v("map")]),t._v(" 中获取对应的值,并将其作为数据源对象返回。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("Containers")]),t._v(" 是一个用于创建容器的静态工厂,你可以通过它去创建所有类型的容器实例")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{294:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"本地缓存容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#本地缓存容器"}},[t._v("#")]),t._v(" 本地缓存容器")]),t._v(" "),s("p",[t._v("本地缓存可以简单地理解为以 "),s("code",[t._v("Map")]),t._v(" 或其他数据结构形式保存在本地 JVM 缓存中的数据,常见的例子包括系统启动后加载的配置项或字典项。")]),t._v(" "),s("p",[t._v("通过 "),s("code",[t._v("Containers")]),t._v(" 的 "),s("code",[t._v("forMap")]),t._v(" 工厂方法,我们可以快速配置一个数据源容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("当输入一个键值作为 key 时,该容器将从 "),s("code",[t._v("map")]),t._v(" 中获取对应的值,并将其作为数据源对象返回。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("Containers")]),t._v(" 是一个用于创建容器的静态工厂,你可以通过它去创建所有类型的容器实例")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/25.76ad5169.js b/docs/assets/js/25.a685ce95.js similarity index 99% rename from docs/assets/js/25.76ad5169.js rename to docs/assets/js/25.a685ce95.js index 8e1e1240..94736dd5 100644 --- a/docs/assets/js/25.76ad5169.js +++ b/docs/assets/js/25.a685ce95.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{297:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"_2-2-1-基本使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-1-基本使用"}},[t._v("#")]),t._v(" 2.2.1. 基本使用")]),t._v(" "),s("p",[t._v("我们可以使用 "),s("code",[t._v("Containers.forEnum")]),t._v(" 方法基于枚举类快速配置一个枚举数据源:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ONE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"one"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TWO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"two"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 Containers.forEnum 方法构建容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 容器缓存的数据为: {1 = ONE}, {2 = TWO}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"num"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Enum")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getCode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定 key 值为 code")]),t._v("\n")])])]),s("p",[t._v("使用该容器后,可以通过键值(code)从容器中获取对应的枚举实例。")]),t._v(" "),s("p",[t._v("或者,也可以通过建造者构建一个枚举容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EnumContainerBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotatedEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("namespace")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定命名空间")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定提供key值的属性")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定提供value值的属性")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("相比起通过静态工厂方法构建,建造者提供更多的配置项。")]),t._v(" "),s("h2",{attrs:{id:"_2-2-2-可选注解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-2-可选注解"}},[t._v("#")]),t._v(" 2.2.2. 可选注解")]),t._v(" "),s("p",[t._v("除了普通枚举外,我们还可以通过 "),s("code",[t._v("@ContainerEnum")]),t._v(" 注解来进一步定义容器的具体信息:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"AnnotatedEnum"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ONE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"one"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TWO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"two"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 Containers.forEnum 方法构建容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// 容器缓存的数据为: {1 = "one"}, {2 = "two"}')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,我们通过 "),s("code",[t._v("@ContainerEnum")]),t._v(" 注解配置了一些额外的信息:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("namespace")]),t._v(':命名空间为 "AnnotatedEnum",如果不配置,默认为枚举类的 '),s("code",[t._v("Class.getSimpleName()")]),t._v(";")]),t._v(" "),s("li",[s("code",[t._v("key")]),t._v(":数据源对象的 key 值取枚举项的 key 字段值,如果不配置,默认为枚举的 "),s("code",[t._v("Enum.name()")]),t._v(";")]),t._v(" "),s("li",[s("code",[t._v("value")]),t._v(":数据源对象为枚举项的 value 字段值,如果不配置,默认为枚举项本身。")])]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 springboot 中,我们也可以在配置文件中直接扫描路径下的所有枚举类,然后将其注册为容器。")])]),t._v(" "),s("h2",{attrs:{id:"_2-2-3-枚举装配"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-3-枚举装配"}},[t._v("#")]),t._v(" 2.2.3.枚举装配")]),t._v(" "),s("p",[t._v("由于基于枚举的填充操作比较常见,"),s("code",[t._v("crane4j")]),t._v(" 提供了 "),s("code",[t._v("@AssembleEnum")]),t._v(" 注解,用于快速声明此类操作。下面是一个示例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AssembleEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" enumKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" enumValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cnName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cnName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 不遵照 @ContainerEnum 的配置")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AssembleEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useContainerEnum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 遵照 @ContainerEnum 的配置")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" cnName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),t._v(" gender"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("FEMALE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"female"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MALE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"male"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" cnName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" enName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们定义了一个枚举类 "),s("code",[t._v("Gender")]),t._v(",它有 "),s("code",[t._v("code")]),t._v("、"),s("code",[t._v("cnName")]),t._v(" 和 "),s("code",[t._v("enName")]),t._v(" 三个字段。然后,我们在 "),s("code",[t._v("Foo")]),t._v(" 类中声明了两个基于 "),s("code",[t._v("id")]),t._v(" 的装配操作:")]),t._v(" "),s("ol",[s("li",[t._v("第一个装配操作忽略了枚举上的 "),s("code",[t._v("@ContainerEnum")]),t._v(" 配置。它根据 "),s("code",[t._v("Foo.id")]),t._v(" 找到对应的 "),s("code",[t._v("Gender.code")]),t._v(" 枚举项,并将 "),s("code",[t._v("Gender.cnName")]),t._v(" 映射到 "),s("code",[t._v("Foo.cnName")]),t._v(" 字段;")]),t._v(" "),s("li",[t._v("第二个装配操作遵循了枚举上的 "),s("code",[t._v("@ContainerEnum")]),t._v(" 配置。它根据 "),s("code",[t._v("Foo.id")]),t._v(" 找到对应的 "),s("code",[t._v("Gender.code")]),t._v(" 枚举项,并直接将该枚举项映射到 "),s("code",[t._v("Foo.gender")]),t._v(" 字段;")])]),t._v(" "),s("p",[t._v("相比使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解,"),s("code",[t._v("@AssembleEnum")]),t._v(' 简化了声明枚举容器的步骤。具体的内容可以参考后文的 "'),s("strong",[t._v("声明装配操作")]),t._v('" 与 "'),s("strong",[t._v("配置字段映射")]),t._v('" 一节。')])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{295:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"_2-2-1-基本使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-1-基本使用"}},[t._v("#")]),t._v(" 2.2.1. 基本使用")]),t._v(" "),s("p",[t._v("我们可以使用 "),s("code",[t._v("Containers.forEnum")]),t._v(" 方法基于枚举类快速配置一个枚举数据源:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ONE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"one"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TWO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"two"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 Containers.forEnum 方法构建容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 容器缓存的数据为: {1 = ONE}, {2 = TWO}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"num"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Enum")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getCode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定 key 值为 code")]),t._v("\n")])])]),s("p",[t._v("使用该容器后,可以通过键值(code)从容器中获取对应的枚举实例。")]),t._v(" "),s("p",[t._v("或者,也可以通过建造者构建一个枚举容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EnumContainerBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotatedEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("namespace")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定命名空间")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定提供key值的属性")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定提供value值的属性")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("相比起通过静态工厂方法构建,建造者提供更多的配置项。")]),t._v(" "),s("h2",{attrs:{id:"_2-2-2-可选注解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-2-可选注解"}},[t._v("#")]),t._v(" 2.2.2. 可选注解")]),t._v(" "),s("p",[t._v("除了普通枚举外,我们还可以通过 "),s("code",[t._v("@ContainerEnum")]),t._v(" 注解来进一步定义容器的具体信息:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"AnnotatedEnum"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ONE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"one"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TWO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"two"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 Containers.forEnum 方法构建容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// 容器缓存的数据为: {1 = "one"}, {2 = "two"}')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Num")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,我们通过 "),s("code",[t._v("@ContainerEnum")]),t._v(" 注解配置了一些额外的信息:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("namespace")]),t._v(':命名空间为 "AnnotatedEnum",如果不配置,默认为枚举类的 '),s("code",[t._v("Class.getSimpleName()")]),t._v(";")]),t._v(" "),s("li",[s("code",[t._v("key")]),t._v(":数据源对象的 key 值取枚举项的 key 字段值,如果不配置,默认为枚举的 "),s("code",[t._v("Enum.name()")]),t._v(";")]),t._v(" "),s("li",[s("code",[t._v("value")]),t._v(":数据源对象为枚举项的 value 字段值,如果不配置,默认为枚举项本身。")])]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 springboot 中,我们也可以在配置文件中直接扫描路径下的所有枚举类,然后将其注册为容器。")])]),t._v(" "),s("h2",{attrs:{id:"_2-2-3-枚举装配"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-3-枚举装配"}},[t._v("#")]),t._v(" 2.2.3.枚举装配")]),t._v(" "),s("p",[t._v("由于基于枚举的填充操作比较常见,"),s("code",[t._v("crane4j")]),t._v(" 提供了 "),s("code",[t._v("@AssembleEnum")]),t._v(" 注解,用于快速声明此类操作。下面是一个示例:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AssembleEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" enumKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" enumValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cnName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cnName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 不遵照 @ContainerEnum 的配置")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AssembleEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useContainerEnum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 遵照 @ContainerEnum 的配置")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" cnName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),t._v(" gender"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerEnum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequiredArgsConstructor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gender")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("FEMALE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"女"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"female"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MALE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"male"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" cnName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" enName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们定义了一个枚举类 "),s("code",[t._v("Gender")]),t._v(",它有 "),s("code",[t._v("code")]),t._v("、"),s("code",[t._v("cnName")]),t._v(" 和 "),s("code",[t._v("enName")]),t._v(" 三个字段。然后,我们在 "),s("code",[t._v("Foo")]),t._v(" 类中声明了两个基于 "),s("code",[t._v("id")]),t._v(" 的装配操作:")]),t._v(" "),s("ol",[s("li",[t._v("第一个装配操作忽略了枚举上的 "),s("code",[t._v("@ContainerEnum")]),t._v(" 配置。它根据 "),s("code",[t._v("Foo.id")]),t._v(" 找到对应的 "),s("code",[t._v("Gender.code")]),t._v(" 枚举项,并将 "),s("code",[t._v("Gender.cnName")]),t._v(" 映射到 "),s("code",[t._v("Foo.cnName")]),t._v(" 字段;")]),t._v(" "),s("li",[t._v("第二个装配操作遵循了枚举上的 "),s("code",[t._v("@ContainerEnum")]),t._v(" 配置。它根据 "),s("code",[t._v("Foo.id")]),t._v(" 找到对应的 "),s("code",[t._v("Gender.code")]),t._v(" 枚举项,并直接将该枚举项映射到 "),s("code",[t._v("Foo.gender")]),t._v(" 字段;")])]),t._v(" "),s("p",[t._v("相比使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解,"),s("code",[t._v("@AssembleEnum")]),t._v(' 简化了声明枚举容器的步骤。具体的内容可以参考后文的 "'),s("strong",[t._v("声明装配操作")]),t._v('" 与 "'),s("strong",[t._v("配置字段映射")]),t._v('" 一节。')])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/26.0bd1f99f.js b/docs/assets/js/26.23eb335c.js similarity index 99% rename from docs/assets/js/26.0bd1f99f.js rename to docs/assets/js/26.23eb335c.js index ecb38c32..5d7ec790 100644 --- a/docs/assets/js/26.0bd1f99f.js +++ b/docs/assets/js/26.23eb335c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{298:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"_2-3-1-基本使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-1-基本使用"}},[s._v("#")]),s._v(" 2.3.1. 基本使用")]),s._v(" "),t("p",[s._v("可以使用 "),t("code",[s._v("Containers.forConstantClass")]),s._v(" 方法将常量类定义为一个数据源容器:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("THREE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用 Containers.forConstantClass 方法构建容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 容器缓存的数据为: {"ONE" = "one"}, {"TWO" = "two"}, {"THREE" = "three"}')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("forConstantClass")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SimpleAnnotationFinder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("或者,也可以通过建造者构建一个常量容器:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ConstantContainerBuilder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("of")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("namespace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"test"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定容器命名空间")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("onlyPublic")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 扫描所有公有和非公有属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("reverse")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 翻转键值对,即使用属性名作为value,属性值作为key")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("build")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("相比起通过静态工厂方法构建,建造者提供更多的配置项。")]),s._v(" "),t("h2",{attrs:{id:"_2-3-2-可选注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-2-可选注解"}},[s._v("#")]),s._v(" 2.3.2. 可选注解")]),s._v(" "),t("p",[s._v("同样地,我们也支持通过注解配置容器的一些更具体的参数:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n namespace "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定命名空间")]),s._v("\n onlyExplicitlyIncluded "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 是否只保存带有 @Include 注解的属性")]),s._v("\n onlyPublic "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 是否只保存公共变量")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant2")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Include")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// onlyExplicitlyIncluded 为 true 时,仅包含带有该注解的属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Exclude")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 默认情况下排除该属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"THREE"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 指定 key 名称为 "THREE"')]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("SAN")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("这里提供了一些可选的配置:")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("namespace")]),s._v(":构建容器的命名空间;")]),s._v(" "),t("li",[t("code",[s._v("onlyExplicitlyIncluded")]),s._v(":是否只保存带有 "),t("code",[s._v("@Include")]),s._v(" 注解的属性;")]),s._v(" "),t("li",[t("code",[s._v("onlyPublic")]),s._v(":是否只保存公共变量;")])]),s._v(" "),t("p",[s._v("此外,我们还引入了一些内部注解,与 "),t("code",[s._v("Lombok")]),s._v(" 类似,可以配合使用以达到特定的效果:")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("@ContainerConstant.Include")]),s._v(":与 "),t("code",[s._v("onlyExplicitlyIncluded")]),s._v(" 属性配合使用,声明要保留的常量属性;")]),s._v(" "),t("li",[t("code",[s._v("@ContainerConstant.Name")]),s._v(":在将常量属性注册到容器后,使用注解指定的名称替代属性名;")])]),s._v(" "),t("p",[t("strong",[s._v("反转键值对")])]),s._v(" "),t("p",[s._v("除了基本配置之外,还有一个特殊的属性 "),t("code",[s._v("reverse")]),s._v(",将其设置为 "),t("code",[s._v("true")]),s._v(" 后,可以反转常量属性名和属性值的关系。例如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reverse "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("THREE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,通过 "),t("code",[s._v("reverse")]),s._v(" 属性声明了键值对的反转,因此基于该常量类构建的容器可以通过属性值获取属性名。例如,输入 "),t("code",[s._v("one")]),s._v(",则可以获得对应的数据源对象为属性名 "),t("code",[s._v("ONE")]),s._v("。")]),s._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),t("p",[s._v("在 springboot 中,我们也可以在配置文件中直接扫描路径下的所有常量类,然后将其注册为容器。")])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{297:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"_2-3-1-基本使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-1-基本使用"}},[s._v("#")]),s._v(" 2.3.1. 基本使用")]),s._v(" "),t("p",[s._v("可以使用 "),t("code",[s._v("Containers.forConstantClass")]),s._v(" 方法将常量类定义为一个数据源容器:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("THREE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用 Containers.forConstantClass 方法构建容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 容器缓存的数据为: {"ONE" = "one"}, {"TWO" = "two"}, {"THREE" = "three"}')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("forConstantClass")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SimpleAnnotationFinder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("或者,也可以通过建造者构建一个常量容器:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ConstantContainerBuilder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("of")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("namespace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"test"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定容器命名空间")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("onlyPublic")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 扫描所有公有和非公有属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("reverse")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 翻转键值对,即使用属性名作为value,属性值作为key")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("build")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("相比起通过静态工厂方法构建,建造者提供更多的配置项。")]),s._v(" "),t("h2",{attrs:{id:"_2-3-2-可选注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-2-可选注解"}},[s._v("#")]),s._v(" 2.3.2. 可选注解")]),s._v(" "),t("p",[s._v("同样地,我们也支持通过注解配置容器的一些更具体的参数:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n namespace "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定命名空间")]),s._v("\n onlyExplicitlyIncluded "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 是否只保存带有 @Include 注解的属性")]),s._v("\n onlyPublic "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 是否只保存公共变量")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant2")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Include")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// onlyExplicitlyIncluded 为 true 时,仅包含带有该注解的属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Exclude")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 默认情况下排除该属性")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant.Name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"THREE"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 指定 key 名称为 "THREE"')]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("SAN")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("这里提供了一些可选的配置:")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("namespace")]),s._v(":构建容器的命名空间;")]),s._v(" "),t("li",[t("code",[s._v("onlyExplicitlyIncluded")]),s._v(":是否只保存带有 "),t("code",[s._v("@Include")]),s._v(" 注解的属性;")]),s._v(" "),t("li",[t("code",[s._v("onlyPublic")]),s._v(":是否只保存公共变量;")])]),s._v(" "),t("p",[s._v("此外,我们还引入了一些内部注解,与 "),t("code",[s._v("Lombok")]),s._v(" 类似,可以配合使用以达到特定的效果:")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("@ContainerConstant.Include")]),s._v(":与 "),t("code",[s._v("onlyExplicitlyIncluded")]),s._v(" 属性配合使用,声明要保留的常量属性;")]),s._v(" "),t("li",[t("code",[s._v("@ContainerConstant.Name")]),s._v(":在将常量属性注册到容器后,使用注解指定的名称替代属性名;")])]),s._v(" "),t("p",[t("strong",[s._v("反转键值对")])]),s._v(" "),t("p",[s._v("除了基本配置之外,还有一个特殊的属性 "),t("code",[s._v("reverse")]),s._v(",将其设置为 "),t("code",[s._v("true")]),s._v(" 后,可以反转常量属性名和属性值的关系。例如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ContainerConstant")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reverse "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooConstant")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("ONE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"one"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TWO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"two"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("THREE")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"three"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,通过 "),t("code",[s._v("reverse")]),s._v(" 属性声明了键值对的反转,因此基于该常量类构建的容器可以通过属性值获取属性名。例如,输入 "),t("code",[s._v("one")]),s._v(",则可以获得对应的数据源对象为属性名 "),t("code",[s._v("ONE")]),s._v("。")]),s._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),t("p",[s._v("在 springboot 中,我们也可以在配置文件中直接扫描路径下的所有常量类,然后将其注册为容器。")])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/27.8fe7dd6c.js b/docs/assets/js/27.f0c704aa.js similarity index 99% rename from docs/assets/js/27.8fe7dd6c.js rename to docs/assets/js/27.f0c704aa.js index 053ff6c0..1d2be59b 100644 --- a/docs/assets/js/27.8fe7dd6c.js +++ b/docs/assets/js/27.f0c704aa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{301:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"lambda容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#lambda容器"}},[t._v("#")]),t._v(" Lambda容器")]),t._v(" "),a("p",[t._v("可以使用 "),a("code",[t._v("LambdaContainer")]),t._v(" 将任何接受"),a("code",[t._v("Collection")]),t._v("集合并返回"),a("code",[t._v("Map")]),t._v("集合的 lambda 表达式定义为容器:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定义Lambda容器,接受key值,并返回按key分组的数据源对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" keys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取全局上下文并注册容器")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtils")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconfiguration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("其中,方法数据源的函数式接口 "),a("code",[t._v("DataProvider")]),t._v(" 也提供了一些便捷的工厂方法:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 固定返回某个集合")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" provider1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fixed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collections")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("emptyMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" provider1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 总是返回空集合")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" provider2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" provider2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("与常量数据源类似,我们同样通过获取 "),a("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例并手动注册该数据源容器。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{306:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"lambda容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#lambda容器"}},[t._v("#")]),t._v(" Lambda容器")]),t._v(" "),a("p",[t._v("可以使用 "),a("code",[t._v("LambdaContainer")]),t._v(" 将任何接受"),a("code",[t._v("Collection")]),t._v("集合并返回"),a("code",[t._v("Map")]),t._v("集合的 lambda 表达式定义为容器:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定义Lambda容器,接受key值,并返回按key分组的数据源对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" keys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("identity")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取全局上下文并注册容器")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtils")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconfiguration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("其中,方法数据源的函数式接口 "),a("code",[t._v("DataProvider")]),t._v(" 也提供了一些便捷的工厂方法:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 固定返回某个集合")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" provider1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fixed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collections")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("emptyMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" provider1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 总是返回空集合")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" provider2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" provider2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("与常量数据源类似,我们同样通过获取 "),a("code",[t._v("Crane4jGlobalConfiguration")]),t._v(" 实例并手动注册该数据源容器。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/28.837d50ab.js b/docs/assets/js/28.ed102a63.js similarity index 99% rename from docs/assets/js/28.837d50ab.js rename to docs/assets/js/28.ed102a63.js index 90bce329..9ec5d0c3 100644 --- a/docs/assets/js/28.837d50ab.js +++ b/docs/assets/js/28.ed102a63.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{303:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("通过在方法或类上添加 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解,可以将任意方法适配为方法数据源容器 "),s("code",[t._v("MethodInvokerContainer")]),t._v("。当调用容器时,方法将自动执行,并将方法执行结果作为数据源对象返回。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-1-声明方法数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-1-声明方法数据源"}},[t._v("#")]),t._v(" 2.5.1.声明方法数据源")]),t._v(" "),s("p",[s("strong",[t._v("直接声明")])]),t._v(" "),s("p",[t._v("可以直接在类上添加 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解,将方法声明为数据源。")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Foo,并且需要按 id 分组")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onoToOneMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在 Spring 环境中,当项目启动时,在后处理阶段会扫描该方法并将其注册为命名空间为 "),s("code",[t._v("onoToOneMethod")]),t._v(" 的数据源容器。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("resultKey")]),t._v(" 默认支持链式操作符,可以通过 "),s("code",[t._v("xx.xx.xx")]),t._v(" 的方式访问内部对象的属性。")])]),t._v(" "),s("p",[s("strong",[t._v("间接声明")])]),t._v(" "),s("p",[t._v("还可以在类上声明方法数据源,但需要额外使用 "),s("code",[t._v("bindMethod")]),t._v(" 属性进行方法绑定。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 父类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SuperClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onoToOneMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 子类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Foo,并且需要按 id 分组")]),t._v("\n bindMethod "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定方法名称,如果存在重载方法,也可以额外的指明要绑定的方法的参数类型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChildClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SuperClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们在 "),s("code",[t._v("ChildClass")]),t._v(" 中将父类 "),s("code",[t._v("SuperClass")]),t._v(" 中的 "),s("code",[t._v("onoToOneMethod")]),t._v(" 方法声明为方法数据源容器。")]),t._v(" "),s("p",[s("strong",[t._v("可以作为数据源源的方法可以/需要具备下述特征")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("可以是实例方法或静态方法;")]),t._v(" "),s("li",[t._v("可以是无参方法或有参方法,如果是有参方法,则第一个参数必须是 "),s("code",[t._v("Collection")]),t._v(" 类型;")]),t._v(" "),s("li",[t._v("方法必须有返回值,可以是与 "),s("code",[t._v("resultType")]),t._v(" 类型对应的对象、对象数组或集合,或者是 "),s("code",[t._v("Map")]),t._v(" 集合;")])]),t._v(" "),s("h2",{attrs:{id:"_2-5-2-对结果分组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-对结果分组"}},[t._v("#")]),t._v(" 2.5.2.对结果分组")]),t._v(" "),s("p",[t._v("由于数据源容器的返回值需要按照 key 分组,因此注解必须通过 "),s("code",[t._v("resultType")]),t._v(" 和 "),s("code",[t._v("resultKey")]),t._v(" 来指定获取数据源对象后用于分组的 key 字段。")]),t._v(" "),s("p",[t._v("一般情况下,方法数据源容器返回的对象与 key 是一对一的关系,这是默认的情况("),s("code",[t._v("MappingType.ONE_TO_ONE")]),t._v(")。不过,我们可以通过 "),s("code",[t._v("type")]),t._v(" 属性来指定映射类型,从而改变结果的分组方式。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-1-一对一"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-1-一对一"}},[t._v("#")]),t._v(" 2.5.2.1.一对一")]),t._v(" "),s("p",[t._v("即一个输入的 key 值对应一个数据源对象,类型为 "),s("code",[t._v("MappingType.ONE_TO_ONE")]),t._v(",这是默认的情况。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-2-一对多"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-2-一对多"}},[t._v("#")]),t._v(" 2.5.2.2.一对多")]),t._v(" "),s("p",[t._v("即一个输入的 key 值对应一个数据源集合,类型为 "),s("code",[t._v("MappingType.ONE_TO_MANY")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,如果有一个方法根据 "),s("code",[t._v("classId")]),t._v(" 获取 "),s("code",[t._v("student")]),t._v(" 对象,希望返回的 "),s("code",[t._v("student")]),t._v(" 对象可以按照 "),s("code",[t._v("classId")]),t._v(" 分组:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"classId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Student,并且需要按 classId 分组")]),t._v("\n type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ONE_TO_MANY")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象与待处理对象类型为一对多,即一个处理对象的 key 值对应一个数据源对象的 key")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStudentByClassIds")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" classIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("该方法适配为数据源容器后,将接受 "),s("code",[t._v("classId")]),t._v(" 集合,并返回按 "),s("code",[t._v("classId")]),t._v(" 分组的 "),s("code",[t._v("student")]),t._v(" 对象("),s("code",[t._v("Map>")]),t._v(")。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-3-不分组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-3-不分组"}},[t._v("#")]),t._v(" 2.5.2.3.不分组")]),t._v(" "),s("p",[t._v("有时候,方法返回值已经是按需分组的 "),s("code",[t._v("Map")]),t._v(" 集合,此时可以指定类型为 "),s("code",[t._v("MappingType.MAPPED")]),t._v(",表示方法已经完成了映射,无需进行额外的分组。")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MAPPED")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStudentByIds")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" ids"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,"),s("code",[t._v("getStudentByIds")]),t._v(" 方法返回值已经是按 "),s("code",[t._v("id")]),t._v(" 分组的 "),s("code",[t._v("Student")]),t._v(" 对象集合,因此无需进行额外的分组,也不需要指定 "),s("code",[t._v("resultType")]),t._v(" 和 "),s("code",[t._v("resultKey")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-4-数据源容器工厂"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-4-数据源容器工厂"}},[t._v("#")]),t._v(" 2.5.4.数据源容器工厂")]),t._v(" "),s("p",[t._v("类似于 "),s("code",[t._v("Spring")]),t._v(" 处理 "),s("code",[t._v("@EventListener")]),t._v(" 注解,"),s("code",[t._v("cranej4")]),t._v(" 通过基于注解处理器 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 处理带有 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的方法。它会选择优先级最高的数据源容器工厂 "),s("code",[t._v("MethodContainerFactory")]),t._v(" 将带有注解的方法适配为数据源容器。")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 默认提供了两种工厂:"),s("code",[t._v("DefaultMethodContainerFactory")]),t._v(" 和 "),s("code",[t._v("CacheableMethodContainerFactory")]),t._v("。分别用于处理带有 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的方法和带有 "),s("code",[t._v("@ContainerCache")]),t._v(" 注解的方法。")]),t._v(" "),s("p",[t._v("用户也可以通过实现 "),s("code",[t._v("MethodContainerFactory")]),t._v(" 接口并提高优先级,然后将其声明为 Spring 上下文的 bean 自动注册,或手动将其注册到注解处理器中,以实现自定义逻辑。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-5-注册方法数据源容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-5-注册方法数据源容器"}},[t._v("#")]),t._v(" 2.5.5.注册方法数据源容器")]),t._v(" "),s("p",[t._v("在 Spring 环境中,只要方法所在的 bean 被 Spring 管理,这些方法就会自动适配为方法数据源容器,并在全局配置中注册。")]),t._v(" "),s("p",[t._v("在非 Spring 环境中,可以使用 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 手动扫描类中的方法,并创建方法数据源容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 配置反射工厂与注解查找器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" propertyOperator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getPropertyOperator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotationFinder")]),t._v(" annotationFinder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 配置方法数据源工厂")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" factories "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultMethodContainerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("propertyOperator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" annotationFinder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 扫描类中的方法,创建方法数据源容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerAnnotationProcessor")]),t._v(" processor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerAnnotationProcessor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" factories"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" containers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" processor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("process")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取全局上下文并注册容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtils")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncontainers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("以上代码配置了反射工厂与注解查找器,并创建了方法数据源工厂集合。然后使用注解处理器 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 扫描类中的方法,并创建方法数据源容器。最后,将创建的容器注册到全局配置中。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{298:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("通过在方法或类上添加 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解,可以将任意方法适配为方法数据源容器 "),s("code",[t._v("MethodInvokerContainer")]),t._v("。当调用容器时,方法将自动执行,并将方法执行结果作为数据源对象返回。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-1-声明方法数据源"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-1-声明方法数据源"}},[t._v("#")]),t._v(" 2.5.1.声明方法数据源")]),t._v(" "),s("p",[s("strong",[t._v("直接声明")])]),t._v(" "),s("p",[t._v("可以直接在类上添加 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解,将方法声明为数据源。")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Foo,并且需要按 id 分组")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onoToOneMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在 Spring 环境中,当项目启动时,在后处理阶段会扫描该方法并将其注册为命名空间为 "),s("code",[t._v("onoToOneMethod")]),t._v(" 的数据源容器。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("resultKey")]),t._v(" 默认支持链式操作符,可以通过 "),s("code",[t._v("xx.xx.xx")]),t._v(" 的方式访问内部对象的属性。")])]),t._v(" "),s("p",[s("strong",[t._v("间接声明")])]),t._v(" "),s("p",[t._v("还可以在类上声明方法数据源,但需要额外使用 "),s("code",[t._v("bindMethod")]),t._v(" 属性进行方法绑定。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 父类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SuperClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onoToOneMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 子类")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Foo,并且需要按 id 分组")]),t._v("\n bindMethod "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onoToOneMethod"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 指定方法名称,如果存在重载方法,也可以额外的指明要绑定的方法的参数类型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChildClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SuperClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,我们在 "),s("code",[t._v("ChildClass")]),t._v(" 中将父类 "),s("code",[t._v("SuperClass")]),t._v(" 中的 "),s("code",[t._v("onoToOneMethod")]),t._v(" 方法声明为方法数据源容器。")]),t._v(" "),s("p",[s("strong",[t._v("可以作为数据源源的方法可以/需要具备下述特征")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("可以是实例方法或静态方法;")]),t._v(" "),s("li",[t._v("可以是无参方法或有参方法,如果是有参方法,则第一个参数必须是 "),s("code",[t._v("Collection")]),t._v(" 类型;")]),t._v(" "),s("li",[t._v("方法必须有返回值,可以是与 "),s("code",[t._v("resultType")]),t._v(" 类型对应的对象、对象数组或集合,或者是 "),s("code",[t._v("Map")]),t._v(" 集合;")])]),t._v(" "),s("h2",{attrs:{id:"_2-5-2-对结果分组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-对结果分组"}},[t._v("#")]),t._v(" 2.5.2.对结果分组")]),t._v(" "),s("p",[t._v("由于数据源容器的返回值需要按照 key 分组,因此注解必须通过 "),s("code",[t._v("resultType")]),t._v(" 和 "),s("code",[t._v("resultKey")]),t._v(" 来指定获取数据源对象后用于分组的 key 字段。")]),t._v(" "),s("p",[t._v("一般情况下,方法数据源容器返回的对象与 key 是一对一的关系,这是默认的情况("),s("code",[t._v("MappingType.ONE_TO_ONE")]),t._v(")。不过,我们可以通过 "),s("code",[t._v("type")]),t._v(" 属性来指定映射类型,从而改变结果的分组方式。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-1-一对一"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-1-一对一"}},[t._v("#")]),t._v(" 2.5.2.1.一对一")]),t._v(" "),s("p",[t._v("即一个输入的 key 值对应一个数据源对象,类型为 "),s("code",[t._v("MappingType.ONE_TO_ONE")]),t._v(",这是默认的情况。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-2-一对多"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-2-一对多"}},[t._v("#")]),t._v(" 2.5.2.2.一对多")]),t._v(" "),s("p",[t._v("即一个输入的 key 值对应一个数据源集合,类型为 "),s("code",[t._v("MappingType.ONE_TO_MANY")]),t._v("。")]),t._v(" "),s("p",[t._v("例如,如果有一个方法根据 "),s("code",[t._v("classId")]),t._v(" 获取 "),s("code",[t._v("student")]),t._v(" 对象,希望返回的 "),s("code",[t._v("student")]),t._v(" 对象可以按照 "),s("code",[t._v("classId")]),t._v(" 分组:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student-class"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n resultType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resultKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"classId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象类型为 Student,并且需要按 classId 分组")]),t._v("\n type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ONE_TO_MANY")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回的数据源对象与待处理对象类型为一对多,即一个处理对象的 key 值对应一个数据源对象的 key")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStudentByClassIds")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" classIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("该方法适配为数据源容器后,将接受 "),s("code",[t._v("classId")]),t._v(" 集合,并返回按 "),s("code",[t._v("classId")]),t._v(" 分组的 "),s("code",[t._v("student")]),t._v(" 对象("),s("code",[t._v("Map>")]),t._v(")。")]),t._v(" "),s("h3",{attrs:{id:"_2-5-2-3-不分组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-3-不分组"}},[t._v("#")]),t._v(" 2.5.2.3.不分组")]),t._v(" "),s("p",[t._v("有时候,方法返回值已经是按需分组的 "),s("code",[t._v("Map")]),t._v(" 集合,此时可以指定类型为 "),s("code",[t._v("MappingType.MAPPED")]),t._v(",表示方法已经完成了映射,无需进行额外的分组。")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("namespace "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MAPPED")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStudentByIds")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" ids"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,"),s("code",[t._v("getStudentByIds")]),t._v(" 方法返回值已经是按 "),s("code",[t._v("id")]),t._v(" 分组的 "),s("code",[t._v("Student")]),t._v(" 对象集合,因此无需进行额外的分组,也不需要指定 "),s("code",[t._v("resultType")]),t._v(" 和 "),s("code",[t._v("resultKey")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-4-数据源容器工厂"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-4-数据源容器工厂"}},[t._v("#")]),t._v(" 2.5.4.数据源容器工厂")]),t._v(" "),s("p",[t._v("类似于 "),s("code",[t._v("Spring")]),t._v(" 处理 "),s("code",[t._v("@EventListener")]),t._v(" 注解,"),s("code",[t._v("cranej4")]),t._v(" 通过基于注解处理器 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 处理带有 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的方法。它会选择优先级最高的数据源容器工厂 "),s("code",[t._v("MethodContainerFactory")]),t._v(" 将带有注解的方法适配为数据源容器。")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 默认提供了两种工厂:"),s("code",[t._v("DefaultMethodContainerFactory")]),t._v(" 和 "),s("code",[t._v("CacheableMethodContainerFactory")]),t._v("。分别用于处理带有 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的方法和带有 "),s("code",[t._v("@ContainerCache")]),t._v(" 注解的方法。")]),t._v(" "),s("p",[t._v("用户也可以通过实现 "),s("code",[t._v("MethodContainerFactory")]),t._v(" 接口并提高优先级,然后将其声明为 Spring 上下文的 bean 自动注册,或手动将其注册到注解处理器中,以实现自定义逻辑。")]),t._v(" "),s("h2",{attrs:{id:"_2-5-5-注册方法数据源容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-5-注册方法数据源容器"}},[t._v("#")]),t._v(" 2.5.5.注册方法数据源容器")]),t._v(" "),s("p",[t._v("在 Spring 环境中,只要方法所在的 bean 被 Spring 管理,这些方法就会自动适配为方法数据源容器,并在全局配置中注册。")]),t._v(" "),s("p",[t._v("在非 Spring 环境中,可以使用 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 手动扫描类中的方法,并创建方法数据源容器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 配置反射工厂与注解查找器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropertyOperator")]),t._v(" propertyOperator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getPropertyOperator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotationFinder")]),t._v(" annotationFinder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 配置方法数据源工厂")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" factories "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arrays")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultMethodContainerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("propertyOperator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" annotationFinder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 扫描类中的方法,创建方法数据源容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerAnnotationProcessor")]),t._v(" processor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MethodContainerAnnotationProcessor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" factories"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" containers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" processor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("process")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取全局上下文并注册容器")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtils")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncontainers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("registerContainer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("以上代码配置了反射工厂与注解查找器,并创建了方法数据源工厂集合。然后使用注解处理器 "),s("code",[t._v("MethodContainerAnnotationProcessor")]),t._v(" 扫描类中的方法,并创建方法数据源容器。最后,将创建的容器注册到全局配置中。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/29.689ef35f.js b/docs/assets/js/29.320b2992.js similarity index 97% rename from docs/assets/js/29.689ef35f.js rename to docs/assets/js/29.320b2992.js index 14bc33e2..21f58026 100644 --- a/docs/assets/js/29.689ef35f.js +++ b/docs/assets/js/29.320b2992.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{300:function(a,s,t){"use strict";t.r(s);var n=t(14),e=Object(n.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"对象内省"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#对象内省"}},[a._v("#")]),a._v(" 对象内省")]),a._v(" "),s("p",[a._v("在对象内省中,如果在 "),s("code",[a._v("@Assemble")]),a._v(" 注解中未指定容器的 "),s("code",[a._v("namespace")]),a._v(",默认情况下会使用一个 "),s("code",[a._v("EmptyContainer")]),a._v(" 作为占位符,而不会实际调用容器。相反,它会对待处理的对象进行内省操作,将待处理对象本身作为数据源。")]),a._v(" "),s("p",[a._v("例如:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"alias"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" alias"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("在上述示例中,通过对象内省的方式,将对象的 "),s("code",[a._v("name")]),a._v(" 字段映射到 "),s("code",[a._v("alias")]),a._v(" 字段上。")]),a._v(" "),s("p",[a._v("这个功能通常用于同步冗余的别名字段,可以通过对象内省自动将一个字段的值设置到另一个字段上,从而实现字段值的同步更新。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{309:function(a,s,t){"use strict";t.r(s);var n=t(14),e=Object(n.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"对象内省"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#对象内省"}},[a._v("#")]),a._v(" 对象内省")]),a._v(" "),s("p",[a._v("在对象内省中,如果在 "),s("code",[a._v("@Assemble")]),a._v(" 注解中未指定容器的 "),s("code",[a._v("namespace")]),a._v(",默认情况下会使用一个 "),s("code",[a._v("EmptyContainer")]),a._v(" 作为占位符,而不会实际调用容器。相反,它会对待处理的对象进行内省操作,将待处理对象本身作为数据源。")]),a._v(" "),s("p",[a._v("例如:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"alias"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" alias"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("在上述示例中,通过对象内省的方式,将对象的 "),s("code",[a._v("name")]),a._v(" 字段映射到 "),s("code",[a._v("alias")]),a._v(" 字段上。")]),a._v(" "),s("p",[a._v("这个功能通常用于同步冗余的别名字段,可以通过对象内省自动将一个字段的值设置到另一个字段上,从而实现字段值的同步更新。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/3.fce17fa5.js b/docs/assets/js/3.673ac862.js similarity index 60% rename from docs/assets/js/3.fce17fa5.js rename to docs/assets/js/3.673ac862.js index fc147846..2eb44622 100644 --- a/docs/assets/js/3.fce17fa5.js +++ b/docs/assets/js/3.673ac862.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{254:function(t,e,n){},277:function(t,e,n){"use strict";n(254)},325:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:(t,{props:e,slots:n})=>t("span",{class:["badge",e.type],style:{verticalAlign:e.vertical}},e.text||n().default)},p=(n(277),n(14)),l=Object(p.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=l.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{256:function(t,e,n){},279:function(t,e,n){"use strict";n(256)},325:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:(t,{props:e,slots:n})=>t("span",{class:["badge",e.type],style:{verticalAlign:e.vertical}},e.text||n().default)},p=(n(279),n(14)),l=Object(p.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=l.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/30.37cebd53.js b/docs/assets/js/30.99bb9a01.js similarity index 99% rename from docs/assets/js/30.37cebd53.js rename to docs/assets/js/30.99bb9a01.js index 6c1b8e81..1b1bfa94 100644 --- a/docs/assets/js/30.37cebd53.js +++ b/docs/assets/js/30.99bb9a01.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{304:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"自定义容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#自定义容器"}},[s._v("#")]),s._v(" 自定义容器")]),s._v(" "),t("p",[s._v("用户可以通过实现 "),t("code",[s._v("Container")]),s._v(" 接口来自定义容器,并将其声明为 "),t("code",[s._v("@Bean")]),s._v(" 或 "),t("code",[s._v("@Component")]),s._v(",以便在程序中使用。")]),s._v(" "),t("p",[s._v("下面是一个示例:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Component")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@RequiredArgsConstructor")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserContainer")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("implements")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserService")]),s._v(" userService"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getNamespace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collection")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" ids"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" users "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" userService"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("listByIds")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ids"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" users"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toMap")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("::")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Function")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("identity")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,我们实现了 "),t("code",[s._v("Container")]),s._v(" 接口,并创建了一个根据用户ID返回"),t("code",[s._v("UserDO")]),s._v("集合的数据源容器。")]),s._v(" "),t("p",[s._v("通过添加 "),t("code",[s._v("@Component")]),s._v(" 注解,将其交给 Spring 容器管理。随后,您可以在其他地方通过命名空间 "),t("code",[s._v("user")]),s._v(" 来引用该容器。")]),s._v(" "),t("p",[s._v("在非 Spring 环境中,您可以手动注册该容器,方法与常量数据源容器或 lambda 表达式数据源容器相似。首先,获取 "),t("code",[s._v("Crane4jGlobalConfiguration")]),s._v(" 对象,然后将自定义容器注册到该全局配置中。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{300:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"自定义容器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#自定义容器"}},[s._v("#")]),s._v(" 自定义容器")]),s._v(" "),t("p",[s._v("用户可以通过实现 "),t("code",[s._v("Container")]),s._v(" 接口来自定义容器,并将其声明为 "),t("code",[s._v("@Bean")]),s._v(" 或 "),t("code",[s._v("@Component")]),s._v(",以便在程序中使用。")]),s._v(" "),t("p",[s._v("下面是一个示例:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Component")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@RequiredArgsConstructor")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserContainer")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("implements")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserService")]),s._v(" userService"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getNamespace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n \n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collection")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" ids"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" users "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" userService"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("listByIds")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ids"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" users"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("stream")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("collect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toMap")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserDO")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("::")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Function")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("identity")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,我们实现了 "),t("code",[s._v("Container")]),s._v(" 接口,并创建了一个根据用户ID返回"),t("code",[s._v("UserDO")]),s._v("集合的数据源容器。")]),s._v(" "),t("p",[s._v("通过添加 "),t("code",[s._v("@Component")]),s._v(" 注解,将其交给 Spring 容器管理。随后,您可以在其他地方通过命名空间 "),t("code",[s._v("user")]),s._v(" 来引用该容器。")]),s._v(" "),t("p",[s._v("在非 Spring 环境中,您可以手动注册该容器,方法与常量数据源容器或 lambda 表达式数据源容器相似。首先,获取 "),t("code",[s._v("Crane4jGlobalConfiguration")]),s._v(" 对象,然后将自定义容器注册到该全局配置中。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/32.5024029a.js b/docs/assets/js/32.4f066023.js similarity index 99% rename from docs/assets/js/32.5024029a.js rename to docs/assets/js/32.4f066023.js index 5219175b..ae013e92 100644 --- a/docs/assets/js/32.5024029a.js +++ b/docs/assets/js/32.4f066023.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{305:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),t("p",[s._v("在默认情况下,"),t("code",[s._v("Container")]),s._v(" 总是用于根据指定的 key 值查询对应的数据源,但是在有些情况下,我们可能需要同时根据多个 key 值,或一些复杂的自定义条件确认一个与待处理对象唯一对应的数据源对象。")]),s._v(" "),t("p",[s._v("为此,"),t("code",[s._v("crane4j")]),s._v(" 支持直接将待填充的对象直接作为 key 值传入容器,由用户自行决定要如何返回数据源,此类容器称为“"),t("strong",[s._v("对象容器")]),s._v("”。")]),s._v(" "),t("p",[s._v("对象容器可以是任何类型的容器,只要它"),t("strong",[s._v("接受待处理对象本身,并且返回以待填充对象本身分组的数据源对象集合")]),s._v("即可。")]),s._v(" "),t("h2",{attrs:{id:"使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#使用"}},[s._v("#")]),s._v(" 使用")]),s._v(" "),t("p",[s._v("比如,我们现有待填充对象 "),t("code",[s._v("Foo")]),s._v(":")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo_info"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 直接以当前的 Foo 对象作为 key,去数据源容器中查询")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Data")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" code"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("我们需要根据 id 和 code 去确认一个对应的 name,此时,我们直接在类上添加 "),t("code",[s._v("@Assemble")]),s._v(" 注解而不指定任何的 key 值,那么该装配操作执行时,将直接把待填充的 "),t("code",[s._v("Foo")]),s._v(" 对象作为 key 值传入命名空间为 "),t("code",[s._v("foo_info")]),s._v(" 容器中。")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("selectFooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collection")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 根据 foo 的 id 和 code 查询对应的 FooInfo 对象,并按 Foo 实例分组")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 构建对象容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" objectContainer "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("forLambda")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo_info"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" foos "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" data "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("selectFooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 获取全局上下文并注册容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Crane4jGlobalConfiguration")]),s._v(" configuration "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SpringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Crane4jGlobalConfiguration")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\nconfiguration"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("registerContainer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("objectContainer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("这里需要注意的是,"),t("code",[s._v("Container")]),s._v(" 返回的数据必须按"),t("strong",[s._v("入参的对象实例本身")]),s._v("分组,如果重写了 "),t("code",[s._v("equals")]),s._v(" 或者 "),t("code",[s._v("hashCode")]),s._v(" 需要格外注意。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{304:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),t("p",[s._v("在默认情况下,"),t("code",[s._v("Container")]),s._v(" 总是用于根据指定的 key 值查询对应的数据源,但是在有些情况下,我们可能需要同时根据多个 key 值,或一些复杂的自定义条件确认一个与待处理对象唯一对应的数据源对象。")]),s._v(" "),t("p",[s._v("为此,"),t("code",[s._v("crane4j")]),s._v(" 支持直接将待填充的对象直接作为 key 值传入容器,由用户自行决定要如何返回数据源,此类容器称为“"),t("strong",[s._v("对象容器")]),s._v("”。")]),s._v(" "),t("p",[s._v("对象容器可以是任何类型的容器,只要它"),t("strong",[s._v("接受待处理对象本身,并且返回以待填充对象本身分组的数据源对象集合")]),s._v("即可。")]),s._v(" "),t("h2",{attrs:{id:"使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#使用"}},[s._v("#")]),s._v(" 使用")]),s._v(" "),t("p",[s._v("比如,我们现有待填充对象 "),t("code",[s._v("Foo")]),s._v(":")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo_info"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 直接以当前的 Foo 对象作为 key,去数据源容器中查询")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Data")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" code"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("我们需要根据 id 和 code 去确认一个对应的 name,此时,我们直接在类上添加 "),t("code",[s._v("@Assemble")]),s._v(" 注解而不指定任何的 key 值,那么该装配操作执行时,将直接把待填充的 "),t("code",[s._v("Foo")]),s._v(" 对象作为 key 值传入命名空间为 "),t("code",[s._v("foo_info")]),s._v(" 容器中。")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("selectFooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collection")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 根据 foo 的 id 和 code 查询对应的 FooInfo 对象,并按 Foo 实例分组")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 构建对象容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" objectContainer "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Containers")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("forLambda")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo_info"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" foos "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Map")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" data "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("selectFooInfo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 获取全局上下文并注册容器")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Crane4jGlobalConfiguration")]),s._v(" configuration "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SpringUtils")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getBean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Crane4jGlobalConfiguration")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\nconfiguration"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("registerContainer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("objectContainer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("这里需要注意的是,"),t("code",[s._v("Container")]),s._v(" 返回的数据必须按"),t("strong",[s._v("入参的对象实例本身")]),s._v("分组,如果重写了 "),t("code",[s._v("equals")]),s._v(" 或者 "),t("code",[s._v("hashCode")]),s._v(" 需要格外注意。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/33.2808df82.js b/docs/assets/js/33.486018b2.js similarity index 98% rename from docs/assets/js/33.2808df82.js rename to docs/assets/js/33.486018b2.js index 1e283fef..7984e782 100644 --- a/docs/assets/js/33.2808df82.js +++ b/docs/assets/js/33.486018b2.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{314:function(a,t,v){"use strict";v.r(t);var _=v(14),e=Object(_.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"一、什么是配置解析器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#一、什么是配置解析器"}},[a._v("#")]),a._v(" 一、什么是配置解析器")]),a._v(" "),t("p",[a._v("// TODO")]),a._v(" "),t("h2",{attrs:{id:"二、运行流程"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#二、运行流程"}},[a._v("#")]),a._v(" 二、运行流程")]),a._v(" "),t("ul",[t("li",[a._v("元素分拣,"),t("code",[a._v("Class")]),a._v(" / "),t("code",[a._v("Field")]),a._v(" 其他;")]),a._v(" "),t("li",[a._v("层级结构扫描;")]),a._v(" "),t("li",[a._v("操作注解处理器链的执行;")]),a._v(" "),t("li",[a._v("将注解解析为操作配置;")]),a._v(" "),t("li",[a._v("2 + 1 级缓存,与最终配置的组装;")]),a._v(" "),t("li",[a._v("未完善的 "),t("code",[a._v("active")]),a._v(" 问题;")])]),a._v(" "),t("h2",{attrs:{id:"三、不同版本的实现"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#三、不同版本的实现"}},[a._v("#")]),a._v(" 三、不同版本的实现")]),a._v(" "),t("h3",{attrs:{id:"_1、crane-时期"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1、crane-时期"}},[a._v("#")]),a._v(" 1、crane 时期")]),a._v(" "),t("p",[a._v("类级注解解析器 "),t("code",[a._v("ClassAnnotationConfigurationParser")]),a._v(" 与属性注解解析器 "),t("code",[a._v("FieldAnnotationConfigurationParser")]),a._v("。")]),a._v(" "),t("h3",{attrs:{id:"_2、v1-0-1-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2、v1-0-1-2"}},[a._v("#")]),a._v(" 2、v1.0 - 1.2")]),a._v(" "),t("p",[a._v("通用解析器 "),t("code",[a._v("AnnotationAwareBeanOperationParser")]),a._v(" 的出现,将 "),t("code",[a._v("Class")]),a._v(" 与 "),t("code",[a._v("Field")]),a._v(" 合二为一。")]),a._v(" "),t("h3",{attrs:{id:"_3、v1-3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3、v1-3"}},[a._v("#")]),a._v(" 3、v1.3")]),a._v(" "),t("p",[a._v("v1.3 只有预览版本而无正式版,严格真正的 "),t("code",[a._v("2.0.0-ALPHA")]),a._v(" 其实是它。")]),a._v(" "),t("p",[a._v("层级化扫描注解解析器 "),t("code",[a._v("TypeHierarchyBeanOperationParser")]),a._v(" 与操作注解解析器 "),t("code",[a._v("OperationAnnotationResolver")]),a._v("。\n流水线模式,围绕同一个上下文的装配操作。")]),a._v(" "),t("h3",{attrs:{id:"_4、v2-0"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4、v2-0"}},[a._v("#")]),a._v(" 4、v2.0")]),a._v(" "),t("p",[a._v("操作注解处理器 "),t("code",[a._v("OperationAnnotationHandler")]),a._v(",职责更加明确,使用更灵活。")]),a._v(" "),t("p",[a._v("支持处理一切基于 "),t("code",[a._v("AnnotatedElement")]),a._v(",为操作者接口的实现提供了基础。")]),a._v(" "),t("p",[a._v("参考 spring 扫描/构建 "),t("code",[a._v("BeanDefinition")]),a._v(" 的模式,每种注解、每个层级结构的解析结果进行独立解析独立缓存,并最终组装为最终的配置对象。")]),a._v(" "),t("h2",{attrs:{id:"四、优化和调试"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#四、优化和调试"}},[a._v("#")]),a._v(" 四、优化和调试")]),a._v(" "),t("h3",{attrs:{id:"_1、可以打断点的关键方法"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1、可以打断点的关键方法"}},[a._v("#")]),a._v(" 1、可以打断点的关键方法")]),a._v(" "),t("h3",{attrs:{id:"_2、可以优化的地方"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2、可以优化的地方"}},[a._v("#")]),a._v(" 2、可以优化的地方")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{305:function(a,t,v){"use strict";v.r(t);var _=v(14),e=Object(_.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"一、什么是配置解析器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#一、什么是配置解析器"}},[a._v("#")]),a._v(" 一、什么是配置解析器")]),a._v(" "),t("p",[a._v("// TODO")]),a._v(" "),t("h2",{attrs:{id:"二、运行流程"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#二、运行流程"}},[a._v("#")]),a._v(" 二、运行流程")]),a._v(" "),t("ul",[t("li",[a._v("元素分拣,"),t("code",[a._v("Class")]),a._v(" / "),t("code",[a._v("Field")]),a._v(" 其他;")]),a._v(" "),t("li",[a._v("层级结构扫描;")]),a._v(" "),t("li",[a._v("操作注解处理器链的执行;")]),a._v(" "),t("li",[a._v("将注解解析为操作配置;")]),a._v(" "),t("li",[a._v("2 + 1 级缓存,与最终配置的组装;")]),a._v(" "),t("li",[a._v("未完善的 "),t("code",[a._v("active")]),a._v(" 问题;")])]),a._v(" "),t("h2",{attrs:{id:"三、不同版本的实现"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#三、不同版本的实现"}},[a._v("#")]),a._v(" 三、不同版本的实现")]),a._v(" "),t("h3",{attrs:{id:"_1、crane-时期"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1、crane-时期"}},[a._v("#")]),a._v(" 1、crane 时期")]),a._v(" "),t("p",[a._v("类级注解解析器 "),t("code",[a._v("ClassAnnotationConfigurationParser")]),a._v(" 与属性注解解析器 "),t("code",[a._v("FieldAnnotationConfigurationParser")]),a._v("。")]),a._v(" "),t("h3",{attrs:{id:"_2、v1-0-1-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2、v1-0-1-2"}},[a._v("#")]),a._v(" 2、v1.0 - 1.2")]),a._v(" "),t("p",[a._v("通用解析器 "),t("code",[a._v("AnnotationAwareBeanOperationParser")]),a._v(" 的出现,将 "),t("code",[a._v("Class")]),a._v(" 与 "),t("code",[a._v("Field")]),a._v(" 合二为一。")]),a._v(" "),t("h3",{attrs:{id:"_3、v1-3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3、v1-3"}},[a._v("#")]),a._v(" 3、v1.3")]),a._v(" "),t("p",[a._v("v1.3 只有预览版本而无正式版,严格真正的 "),t("code",[a._v("2.0.0-ALPHA")]),a._v(" 其实是它。")]),a._v(" "),t("p",[a._v("层级化扫描注解解析器 "),t("code",[a._v("TypeHierarchyBeanOperationParser")]),a._v(" 与操作注解解析器 "),t("code",[a._v("OperationAnnotationResolver")]),a._v("。\n流水线模式,围绕同一个上下文的装配操作。")]),a._v(" "),t("h3",{attrs:{id:"_4、v2-0"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4、v2-0"}},[a._v("#")]),a._v(" 4、v2.0")]),a._v(" "),t("p",[a._v("操作注解处理器 "),t("code",[a._v("OperationAnnotationHandler")]),a._v(",职责更加明确,使用更灵活。")]),a._v(" "),t("p",[a._v("支持处理一切基于 "),t("code",[a._v("AnnotatedElement")]),a._v(",为操作者接口的实现提供了基础。")]),a._v(" "),t("p",[a._v("参考 spring 扫描/构建 "),t("code",[a._v("BeanDefinition")]),a._v(" 的模式,每种注解、每个层级结构的解析结果进行独立解析独立缓存,并最终组装为最终的配置对象。")]),a._v(" "),t("h2",{attrs:{id:"四、优化和调试"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#四、优化和调试"}},[a._v("#")]),a._v(" 四、优化和调试")]),a._v(" "),t("h3",{attrs:{id:"_1、可以打断点的关键方法"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1、可以打断点的关键方法"}},[a._v("#")]),a._v(" 1、可以打断点的关键方法")]),a._v(" "),t("h3",{attrs:{id:"_2、可以优化的地方"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2、可以优化的地方"}},[a._v("#")]),a._v(" 2、可以优化的地方")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/34.b5cfa96d.js b/docs/assets/js/34.5004cfaf.js similarity index 99% rename from docs/assets/js/34.b5cfa96d.js rename to docs/assets/js/34.5004cfaf.js index 03b416b3..5b2bf7f3 100644 --- a/docs/assets/js/34.b5cfa96d.js +++ b/docs/assets/js/34.5004cfaf.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{308:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),a("p",[t._v("我们将在代码里面使用 "),a("code",[t._v("OperateTemplate")]),t._v(" 或者 "),a("code",[t._v("BeanOperationExecutor")]),t._v(" 完成的填充操作称为手动填充,相比起自动填充,手动填充的适用场景更广,操作的粒度更细。")]),t._v(" "),a("h2",{attrs:{id:"_4-1-1-使用执行器手动填充"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-1-使用执行器手动填充"}},[t._v("#")]),t._v(" 4.1.1.使用执行器手动填充")]),t._v(" "),a("p",[t._v("用户可以先使用配置解析器获得配置,然后再使用执行器完成操作:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取操作配置")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),t._v(" parser "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperations")]),t._v(" operation "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" parser"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 根据操作配置执行填充")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),t._v(" executor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fooService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nexecutor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foos"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" operation"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("这种方式会比较繁琐,不过好处在于获得操作配置对象 "),a("code",[t._v("BeanOperations")]),t._v(" 后可以对已有的配置进行一定程度的调整。")]),t._v(" "),a("h2",{attrs:{id:"_4-1-2-使用-operatetemplate"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-2-使用-operatetemplate"}},[t._v("#")]),t._v(" 4.1.2.使用 OperateTemplate")]),t._v(" "),a("p",[t._v("另一种方式是使用 "),a("code",[t._v("OperateTemplate")]),t._v(",这是 "),a("code",[t._v("crane4j")]),t._v(" 提供的辅助类,命名参考了 Spring 提供的各种 "),a("code",[t._v("XXXTemplate")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fooService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" template "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foos"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[a("code",[t._v("OperateTemplate")]),t._v(" 可以按照默认配置完成整个填充流程,但它也提供了多种重载方法,允许您在参数中指定要使用的组件或过滤器。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{311:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),a("p",[t._v("我们将在代码里面使用 "),a("code",[t._v("OperateTemplate")]),t._v(" 或者 "),a("code",[t._v("BeanOperationExecutor")]),t._v(" 完成的填充操作称为手动填充,相比起自动填充,手动填充的适用场景更广,操作的粒度更细。")]),t._v(" "),a("h2",{attrs:{id:"_4-1-1-使用执行器手动填充"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-1-使用执行器手动填充"}},[t._v("#")]),t._v(" 4.1.1.使用执行器手动填充")]),t._v(" "),a("p",[t._v("用户可以先使用配置解析器获得配置,然后再使用执行器完成操作:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取操作配置")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),t._v(" parser "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationParser")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperations")]),t._v(" operation "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" parser"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 根据操作配置执行填充")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),t._v(" executor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fooService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nexecutor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foos"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" operation"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("这种方式会比较繁琐,不过好处在于获得操作配置对象 "),a("code",[t._v("BeanOperations")]),t._v(" 后可以对已有的配置进行一定程度的调整。")]),t._v(" "),a("h2",{attrs:{id:"_4-1-2-使用-operatetemplate"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-2-使用-operatetemplate"}},[t._v("#")]),t._v(" 4.1.2.使用 OperateTemplate")]),t._v(" "),a("p",[t._v("另一种方式是使用 "),a("code",[t._v("OperateTemplate")]),t._v(",这是 "),a("code",[t._v("crane4j")]),t._v(" 提供的辅助类,命名参考了 Spring 提供的各种 "),a("code",[t._v("XXXTemplate")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fooService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" template "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foos"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[a("code",[t._v("OperateTemplate")]),t._v(" 可以按照默认配置完成整个填充流程,但它也提供了多种重载方法,允许您在参数中指定要使用的组件或过滤器。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/35.f5c0fb32.js b/docs/assets/js/35.996b296a.js similarity index 99% rename from docs/assets/js/35.f5c0fb32.js rename to docs/assets/js/35.996b296a.js index 6072c999..f30517cb 100644 --- a/docs/assets/js/35.f5c0fb32.js +++ b/docs/assets/js/35.996b296a.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[35],{315:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,可以基于 Spring AOP 的切面来实现自动填充方法的参数和返回值,这种方式称为"),s("strong",[t._v("自动填充")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-1-填充方法返回值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-1-填充方法返回值"}},[t._v("#")]),t._v(" 4.2.1.填充方法返回值")]),t._v(" "),s("p",[t._v("基于 "),s("code",[t._v("SpringAOP")]),t._v(",当我们在方法上添加 "),s("code",[t._v("@AutoOperate")]),t._v(" 后,切面类 "),s("code",[t._v("MethodResultAutoOperateAdvisor")]),t._v(" 即可在方法返回时对返回值进行自动填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("返回值类型可以是单个对象、对象数组或对象的 "),s("code",[t._v("Collection")]),t._v(" 集合。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-2-自动填充方法参数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-2-自动填充方法参数"}},[t._v("#")]),t._v(" 4.2.2.自动填充方法参数")]),t._v(" "),s("p",[t._v("基于 "),s("code",[t._v("SpringAOP")]),t._v(",当我们在方法上添加 "),s("code",[t._v("@ArgAutoOperate")]),t._v(" 后,切面类 "),s("code",[t._v("MethodArgumentAutoOperateAdvisor")]),t._v(" 即可在方法执行前对入参进行自动填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.可以注解在参数上")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.可以注解在方法上,此时声明方式类似 swagger")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ArgAutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("与返回值填充类似,填充的数据可以是单个对象、对象数组或对象的集合类型参数,并支持所有返回值自动填充功能的全部功能。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-3-自动类型推断"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-3-自动类型推断"}},[t._v("#")]),t._v(" 4.2.3.自动类型推断")]),t._v(" "),s("p",[t._v("在某些情况下,无法在编译期确定要填充的对象类型。此时,可以不指定 "),s("code",[t._v("type")]),t._v(" 属性,而是在执行拆卸操作时动态推断类型:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 无法确定填充类型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,无法在编译期确定 "),s("code",[t._v("getFooList")]),t._v(" 的返回值类型,因此没有指定 "),s("code",[t._v("type")]),t._v(" 属性。在执行自动填充操作时,会动态推断类型。")]),t._v(" "),s("p",[t._v("这个功能是通过类型解析器 "),s("code",[t._v("TypeResolver")]),t._v(" 实现的。用户可以实现 "),s("code",[t._v("TypeResolver")]),t._v(" 接口来替换默认的类型解析器,以适应特定的需求。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-4-包装类提取"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-4-包装类提取"}},[t._v("#")]),t._v(" 4.2.4.包装类提取")]),t._v(" "),s("p",[t._v("有时候,在"),s("code",[t._v("Controller")]),t._v("中的方法返回值通常会使用通用响应体进行包装,例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("实际上,需要填充的对象并不是"),s("code",[t._v("Result")]),t._v("本身,而是"),s("code",[t._v("Result")]),t._v("中的"),s("code",[t._v("data")]),t._v("字段。除了将"),s("code",[t._v("Result")]),t._v("作为填充对象并在"),s("code",[t._v("data")]),t._v("上添加"),s("code",[t._v("@Disassemble")]),t._v("注解进行拆卸外,还可以直接通过"),s("code",[t._v("on")]),t._v("属性提取特定属性值进行填充。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" on "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("需要注意的是,如果指定了字段值提取,那么类型推断时将以提取出的字段值为准。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("on")]),t._v("属性默认支持链式操作符,即通过"),s("code",[t._v("xx.xx.xx")]),t._v("的方式访问内部对象的属性。\n例如,对于常见的"),s("code",[t._v("Result>")]),t._v(",可以使用"),s("code",[t._v("on = data.list")]),t._v("来获取嵌套在 "),s("code",[t._v("PageInfo.list")]),t._v(" 中的待处理数据。")])]),t._v(" "),s("h2",{attrs:{id:"_4-2-5-应用条件表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-5-应用条件表达式"}},[t._v("#")]),t._v(" 4.2.5.应用条件表达式")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("condition")]),t._v(" 属性,可以设置应用条件的表达式。在执行填充之前,将根据表达式的计算结果确定是否执行该次填充。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" condition "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#type != 1 && ${config.enable-fill-foo}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例表示只有当"),s("code",[t._v("type")]),t._v("不等于 "),s("code",[t._v("1")]),t._v(" 且配置文件中的 "),s("code",[t._v("config.enable-fill-foo")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(" 时,才会执行填充操作。")]),t._v(" "),s("p",[t._v("默认的表达式引擎是 SpEL 表达式,因此可以在表达式中使用 "),s("code",[t._v("#result")]),t._v(" 引用返回值,使用 "),s("code",[t._v("#参数名")]),t._v(" 引用方法的入参。返回值可以是布尔值,也可以是字符串"),s("code",[t._v("'true'")]),t._v("或"),s("code",[t._v("'false'")]),t._v("。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 Spring 环境中,默认支持 SpEL 表达式,也可以更换表达式引擎以支持其他类型的表达式。")])]),t._v(" "),s("h2",{attrs:{id:"_4-2-6-分组填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-6-分组填充"}},[t._v("#")]),t._v(" 4.2.6.分组填充")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("includes")]),t._v(" 或 "),s("code",[t._v("excludes")]),t._v(" 属性可以设置本次执行的操作组。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" includes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"base"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,执行填充操作时,只会完成带有 "),s("code",[t._v("base")]),t._v(" 或 "),s("code",[t._v("foo")]),t._v(" 组别的装配/拆卸操作。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-7-指定执行器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-7-指定执行器"}},[t._v("#")]),t._v(" 4.2.7.指定执行器")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("executor")]),t._v(" 属性可以指定本次填充操作的执行器,不同的执行器会对填充操作产生不同的影响。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @AutoOperate(type = Foo.class, executorType = AsyncBeanOperationExecutor.class)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executorType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,指定的 "),s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(" 将按照规定的顺序同步执行填充操作,而 "),s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(" 则支持并发填充。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("关于执行器,请参照"),s("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[t._v("操作执行器")]),t._v("一节")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[35],{310:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("crane4j")]),t._v("中,可以基于 Spring AOP 的切面来实现自动填充方法的参数和返回值,这种方式称为"),s("strong",[t._v("自动填充")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-1-填充方法返回值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-1-填充方法返回值"}},[t._v("#")]),t._v(" 4.2.1.填充方法返回值")]),t._v(" "),s("p",[t._v("基于 "),s("code",[t._v("SpringAOP")]),t._v(",当我们在方法上添加 "),s("code",[t._v("@AutoOperate")]),t._v(" 后,切面类 "),s("code",[t._v("MethodResultAutoOperateAdvisor")]),t._v(" 即可在方法返回时对返回值进行自动填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("返回值类型可以是单个对象、对象数组或对象的 "),s("code",[t._v("Collection")]),t._v(" 集合。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-2-自动填充方法参数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-2-自动填充方法参数"}},[t._v("#")]),t._v(" 4.2.2.自动填充方法参数")]),t._v(" "),s("p",[t._v("基于 "),s("code",[t._v("SpringAOP")]),t._v(",当我们在方法上添加 "),s("code",[t._v("@ArgAutoOperate")]),t._v(" 后,切面类 "),s("code",[t._v("MethodArgumentAutoOperateAdvisor")]),t._v(" 即可在方法执行前对入参进行自动填充:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.可以注解在参数上")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.可以注解在方法上,此时声明方式类似 swagger")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ArgAutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("与返回值填充类似,填充的数据可以是单个对象、对象数组或对象的集合类型参数,并支持所有返回值自动填充功能的全部功能。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-3-自动类型推断"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-3-自动类型推断"}},[t._v("#")]),t._v(" 4.2.3.自动类型推断")]),t._v(" "),s("p",[t._v("在某些情况下,无法在编译期确定要填充的对象类型。此时,可以不指定 "),s("code",[t._v("type")]),t._v(" 属性,而是在执行拆卸操作时动态推断类型:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 无法确定填充类型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,无法在编译期确定 "),s("code",[t._v("getFooList")]),t._v(" 的返回值类型,因此没有指定 "),s("code",[t._v("type")]),t._v(" 属性。在执行自动填充操作时,会动态推断类型。")]),t._v(" "),s("p",[t._v("这个功能是通过类型解析器 "),s("code",[t._v("TypeResolver")]),t._v(" 实现的。用户可以实现 "),s("code",[t._v("TypeResolver")]),t._v(" 接口来替换默认的类型解析器,以适应特定的需求。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-4-包装类提取"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-4-包装类提取"}},[t._v("#")]),t._v(" 4.2.4.包装类提取")]),t._v(" "),s("p",[t._v("有时候,在"),s("code",[t._v("Controller")]),t._v("中的方法返回值通常会使用通用响应体进行包装,例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("T")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("实际上,需要填充的对象并不是"),s("code",[t._v("Result")]),t._v("本身,而是"),s("code",[t._v("Result")]),t._v("中的"),s("code",[t._v("data")]),t._v("字段。除了将"),s("code",[t._v("Result")]),t._v("作为填充对象并在"),s("code",[t._v("data")]),t._v("上添加"),s("code",[t._v("@Disassemble")]),t._v("注解进行拆卸外,还可以直接通过"),s("code",[t._v("on")]),t._v("属性提取特定属性值进行填充。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" on "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("需要注意的是,如果指定了字段值提取,那么类型推断时将以提取出的字段值为准。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[s("code",[t._v("on")]),t._v("属性默认支持链式操作符,即通过"),s("code",[t._v("xx.xx.xx")]),t._v("的方式访问内部对象的属性。\n例如,对于常见的"),s("code",[t._v("Result>")]),t._v(",可以使用"),s("code",[t._v("on = data.list")]),t._v("来获取嵌套在 "),s("code",[t._v("PageInfo.list")]),t._v(" 中的待处理数据。")])]),t._v(" "),s("h2",{attrs:{id:"_4-2-5-应用条件表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-5-应用条件表达式"}},[t._v("#")]),t._v(" 4.2.5.应用条件表达式")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("condition")]),t._v(" 属性,可以设置应用条件的表达式。在执行填充之前,将根据表达式的计算结果确定是否执行该次填充。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" condition "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#type != 1 && ${config.enable-fill-foo}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例表示只有当"),s("code",[t._v("type")]),t._v("不等于 "),s("code",[t._v("1")]),t._v(" 且配置文件中的 "),s("code",[t._v("config.enable-fill-foo")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(" 时,才会执行填充操作。")]),t._v(" "),s("p",[t._v("默认的表达式引擎是 SpEL 表达式,因此可以在表达式中使用 "),s("code",[t._v("#result")]),t._v(" 引用返回值,使用 "),s("code",[t._v("#参数名")]),t._v(" 引用方法的入参。返回值可以是布尔值,也可以是字符串"),s("code",[t._v("'true'")]),t._v("或"),s("code",[t._v("'false'")]),t._v("。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 Spring 环境中,默认支持 SpEL 表达式,也可以更换表达式引擎以支持其他类型的表达式。")])]),t._v(" "),s("h2",{attrs:{id:"_4-2-6-分组填充"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-6-分组填充"}},[t._v("#")]),t._v(" 4.2.6.分组填充")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("includes")]),t._v(" 或 "),s("code",[t._v("excludes")]),t._v(" 属性可以设置本次执行的操作组。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" includes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"base"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,执行填充操作时,只会完成带有 "),s("code",[t._v("base")]),t._v(" 或 "),s("code",[t._v("foo")]),t._v(" 组别的装配/拆卸操作。")]),t._v(" "),s("h2",{attrs:{id:"_4-2-7-指定执行器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-7-指定执行器"}},[t._v("#")]),t._v(" 4.2.7.指定执行器")]),t._v(" "),s("p",[t._v("通过注解的 "),s("code",[t._v("executor")]),t._v(" 属性可以指定本次填充操作的执行器,不同的执行器会对填充操作产生不同的影响。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @AutoOperate(type = Foo.class, executorType = AsyncBeanOperationExecutor.class)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executorType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFoo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,指定的 "),s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(" 将按照规定的顺序同步执行填充操作,而 "),s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(" 则支持并发填充。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("关于执行器,请参照"),s("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[t._v("操作执行器")]),t._v("一节")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/36.80361c01.js b/docs/assets/js/36.c3f4bebc.js similarity index 99% rename from docs/assets/js/36.80361c01.js rename to docs/assets/js/36.c3f4bebc.js index 0b3b49bd..cbbbf22f 100644 --- a/docs/assets/js/36.80361c01.js +++ b/docs/assets/js/36.c3f4bebc.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{310:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("操作执行器 "),s("code",[t._v("BeanOperationExecutor")]),t._v(" 是完成填充操作的核心组件,它决定了如何使用相应的处理器来执行填充和装配操作。")]),t._v(" "),s("p",[t._v("在调用 "),s("code",[t._v("execute")]),t._v(" 方法时,它会执行以下四个步骤:")]),t._v(" "),s("ol",[s("li",[t._v("接收待处理对象和相应的操作配置对象 "),s("code",[t._v("BeanOperations")]),t._v(";")]),t._v(" "),s("li",[t._v("执行拆卸操作,将所有需要处理的嵌套对象展开;")]),t._v(" "),s("li",[t._v("根据对象中各个 "),s("code",[t._v("key")]),t._v(" 字段对应的操作,将对象和相应的装配操作封装为执行对象 "),s("code",[t._v("AssembleExecution")]),t._v(";")]),t._v(" "),s("li",[t._v("最终按照特定的顺序将执行对象 "),s("code",[t._v("AssembleExecution")]),t._v(" 分发给操作处理器 "),s("code",[t._v("AssembleOperationHandler")]),t._v(",完成操作;")])]),t._v(" "),s("p",[t._v("操作执行器决定了操作的执行顺序以及对数据源的访问次数,这是影响执行效率的关键组件之一。")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://img.xiajibagao.top/image-20230221133602215.png",alt:"操作执行器示意图"}})]),t._v(" "),s("h2",{attrs:{id:"_4-3-1-可选实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-1-可选实现"}},[t._v("#")]),t._v(" 4.3.1.可选实现")]),t._v(" "),s("p",[t._v("操作执行器有三种实现,用户可以根据需求自己选择:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("DisorderedBeanOperationExecutor")]),t._v(":同步无序操作执行器,默认使用的操作执行器;")]),t._v(" "),s("li",[s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(":同步有序操作执行器,支持按顺序完成装配操作,但是相对无序执行器在特定情况性能有所影响;")]),t._v(" "),s("li",[s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(":异步操作执行器,默认不注册到 Spring 容器,需要用户自己注册;")])]),t._v(" "),s("p",[t._v("以下是它们的异同点:")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("执行器")]),t._v(" "),s("th",[t._v("是否按顺序执行")]),t._v(" "),s("th",[t._v("一次填充相同容器访问次数")]),t._v(" "),s("th",[t._v("是否异步")]),t._v(" "),s("th",[t._v("是否默认启用")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[s("code",[t._v("AsyncBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("n")]),t._v(" "),s("td",[t._v("√")]),t._v(" "),s("td",[t._v("×")])]),t._v(" "),s("tr",[s("td",[s("code",[t._v("DisorderedBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("√")])]),t._v(" "),s("tr",[s("td",[s("code",[t._v("OrderedBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("√")]),t._v(" "),s("td",[t._v("n")]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("√")])])])]),t._v(" "),s("p",[t._v("其中,一次填充相同容器访问次数,是指当执行填充时,如果在一组填充中同时有 n 个操作都指定了相同的数据源容器,那么在本次填充中该数据源容器会被访问几次。")]),t._v(" "),s("p",[t._v("由于执行器按容器分组批量执行操作会打乱操作间原有顺序,因此目前批量提交与执行顺序不可兼得。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 spring 环境中,异步执行器 "),s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(" 默认是不注册的,要使用的话用户需要自己在 spring 上下文中配置。")])]),t._v(" "),s("h2",{attrs:{id:"_4-3-2-使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-2-使用"}},[t._v("#")]),t._v(" 4.3.2.使用")]),t._v(" "),s("p",[s("strong",[t._v("在手动填充时使用")])]),t._v(" "),s("p",[t._v("当手动填充时,可通过 "),s("code",[t._v("OperateTemplate")]),t._v(" 的指定重载方法设置本次填充操作使用的操作执行器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 从 spring 上下文中获取 OperateTemplate 和 DisorderedBeanOperationExecutor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fooList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" op "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("在自动填充时使用")])]),t._v(" "),s("p",[t._v("当自动填充时,可以在 "),s("code",[t._v("@AutoOperate")]),t._v(" 注解指操作执行器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充返回值")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充参数")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ArgAutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{315:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("操作执行器 "),s("code",[t._v("BeanOperationExecutor")]),t._v(" 是完成填充操作的核心组件,它决定了如何使用相应的处理器来执行填充和装配操作。")]),t._v(" "),s("p",[t._v("在调用 "),s("code",[t._v("execute")]),t._v(" 方法时,它会执行以下四个步骤:")]),t._v(" "),s("ol",[s("li",[t._v("接收待处理对象和相应的操作配置对象 "),s("code",[t._v("BeanOperations")]),t._v(";")]),t._v(" "),s("li",[t._v("执行拆卸操作,将所有需要处理的嵌套对象展开;")]),t._v(" "),s("li",[t._v("根据对象中各个 "),s("code",[t._v("key")]),t._v(" 字段对应的操作,将对象和相应的装配操作封装为执行对象 "),s("code",[t._v("AssembleExecution")]),t._v(";")]),t._v(" "),s("li",[t._v("最终按照特定的顺序将执行对象 "),s("code",[t._v("AssembleExecution")]),t._v(" 分发给操作处理器 "),s("code",[t._v("AssembleOperationHandler")]),t._v(",完成操作;")])]),t._v(" "),s("p",[t._v("操作执行器决定了操作的执行顺序以及对数据源的访问次数,这是影响执行效率的关键组件之一。")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://img.xiajibagao.top/image-20230221133602215.png",alt:"操作执行器示意图"}})]),t._v(" "),s("h2",{attrs:{id:"_4-3-1-可选实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-1-可选实现"}},[t._v("#")]),t._v(" 4.3.1.可选实现")]),t._v(" "),s("p",[t._v("操作执行器有三种实现,用户可以根据需求自己选择:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("DisorderedBeanOperationExecutor")]),t._v(":同步无序操作执行器,默认使用的操作执行器;")]),t._v(" "),s("li",[s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(":同步有序操作执行器,支持按顺序完成装配操作,但是相对无序执行器在特定情况性能有所影响;")]),t._v(" "),s("li",[s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(":异步操作执行器,默认不注册到 Spring 容器,需要用户自己注册;")])]),t._v(" "),s("p",[t._v("以下是它们的异同点:")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("执行器")]),t._v(" "),s("th",[t._v("是否按顺序执行")]),t._v(" "),s("th",[t._v("一次填充相同容器访问次数")]),t._v(" "),s("th",[t._v("是否异步")]),t._v(" "),s("th",[t._v("是否默认启用")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[s("code",[t._v("AsyncBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("n")]),t._v(" "),s("td",[t._v("√")]),t._v(" "),s("td",[t._v("×")])]),t._v(" "),s("tr",[s("td",[s("code",[t._v("DisorderedBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("√")])]),t._v(" "),s("tr",[s("td",[s("code",[t._v("OrderedBeanOperationExecutor")])]),t._v(" "),s("td",[t._v("√")]),t._v(" "),s("td",[t._v("n")]),t._v(" "),s("td",[t._v("×")]),t._v(" "),s("td",[t._v("√")])])])]),t._v(" "),s("p",[t._v("其中,一次填充相同容器访问次数,是指当执行填充时,如果在一组填充中同时有 n 个操作都指定了相同的数据源容器,那么在本次填充中该数据源容器会被访问几次。")]),t._v(" "),s("p",[t._v("由于执行器按容器分组批量执行操作会打乱操作间原有顺序,因此目前批量提交与执行顺序不可兼得。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("在 spring 环境中,异步执行器 "),s("code",[t._v("AsyncBeanOperationExecutor")]),t._v(" 默认是不注册的,要使用的话用户需要自己在 spring 上下文中配置。")])]),t._v(" "),s("h2",{attrs:{id:"_4-3-2-使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-2-使用"}},[t._v("#")]),t._v(" 4.3.2.使用")]),t._v(" "),s("p",[s("strong",[t._v("在手动填充时使用")])]),t._v(" "),s("p",[t._v("当手动填充时,可通过 "),s("code",[t._v("OperateTemplate")]),t._v(" 的指定重载方法设置本次填充操作使用的操作执行器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 从 spring 上下文中获取 OperateTemplate 和 DisorderedBeanOperationExecutor")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),t._v(" operateTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperateTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BeanOperationExecutor")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperateTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("execute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fooList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" op "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("在自动填充时使用")])]),t._v(" "),s("p",[t._v("当自动填充时,可以在 "),s("code",[t._v("@AutoOperate")]),t._v(" 注解指操作执行器:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充返回值")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充参数")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ArgAutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@AutoOperate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DisorderedBeanOperationExecutor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setFooList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" foos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do nothing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/37.54de3722.js b/docs/assets/js/37.9ad99572.js similarity index 99% rename from docs/assets/js/37.54de3722.js rename to docs/assets/js/37.9ad99572.js index 0da2be84..1ec51cc4 100644 --- a/docs/assets/js/37.54de3722.js +++ b/docs/assets/js/37.9ad99572.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{309:function(a,s,t){"use strict";t.r(s);var n=t(14),e=Object(n.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[a._v("#")]),a._v(" 概述")]),a._v(" "),s("p",[s("code",[a._v("crane4j")]),a._v(" 提供 "),s("code",[a._v("MybatisPlus")]),a._v(" 的扩展组件,允许基于 "),s("code",[a._v("MybatisPlus")]),a._v(" 的 "),s("code",[a._v("BaseMapper")]),a._v(" 自动构建数据源容器,以便快速的实现查询关联数据并用于填充。")]),a._v(" "),s("h2",{attrs:{id:"_6-1-1-安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-1-安装"}},[a._v("#")]),a._v(" 6.1.1.安装")]),a._v(" "),s("p",[a._v("先引入 maven 依赖:")]),a._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("\x3c!-- 先引入 crane4j-spring-boot-starter --\x3e")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("top.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("crane4j-spring-boot-starter"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("\x3c!-- 引入 mybatis-plus --\x3e")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("com.baomidou"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("mybatis-plus-boot-starter"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n\t"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n")])])]),s("p",[a._v("然后在启动类上添加 "),s("code",[a._v("@EnableCrane4j")]),a._v(" 或单独添加 "),s("code",[a._v("@EnableCrane4jMybatisPlusExtension")]),a._v(" 注解即可:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@EnableCrane4j")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@SpringBootApplication")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MbossChargeApplication")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("static")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("void")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("SpringApplication")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MbossChargeApplication")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h2",{attrs:{id:"_6-1-2-注册mapper"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-2-注册mapper"}},[a._v("#")]),a._v(" 6.1.2.注册Mapper")]),a._v(" "),s("p",[s("strong",[a._v("懒加载")])]),a._v(" "),s("p",[a._v("在 spring 环境中,用户默认不需要进行额外的操作,"),s("code",[a._v("MybatisPlusQueryContainerProvider")]),a._v(" 会在用户使用时根据 "),s("code",[a._v("beanName")]),a._v(" 自动从 spring 上下文中获得对应的 "),s("code",[a._v("Mapper")]),a._v(",并完成自动注册,即懒加载。")]),a._v(" "),s("p",[s("strong",[a._v("自动注册")])]),a._v(" "),s("p",[a._v("在 spring 环境中,用户也可以指定 "),s("code",[a._v("auto-register-mapper")]),a._v(" 为 "),s("code",[a._v("true")]),a._v(" 开启自动注册,相关配置如下:")]),a._v(" "),s("div",{staticClass:"language-yml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-yml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("mybatis-plus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("auto-register-mapper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 启动自动注册")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 仅注册指定 Mapper")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("excludes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 仅排除指定 Mapper")]),a._v("\n")])])]),s("p",[a._v("在开启自动注册的情况下,spring 上下文中任何符合 "),s("code",[a._v("includes")]),a._v(" 与 "),s("code",[a._v("excludes")]),a._v(" 规则的 "),s("code",[a._v("Mapper")]),a._v(" 都会被注册。")]),a._v(" "),s("p",[s("strong",[a._v("手动注册")])]),a._v(" "),s("p",[a._v("用户也可以获取 "),s("code",[a._v("MybatisPlusQueryContainerProvider")]),a._v(" 进行手动注册:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MybatisPlusQueryContainerProvider")]),a._v(" register "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MybatisPlusQueryContainerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nregister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("registerRepository")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xxxMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("h2",{attrs:{id:"_6-1-3-基本使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-基本使用"}},[a._v("#")]),a._v(" 6.1.3.基本使用")]),a._v(" "),s("p",[a._v("用户可以使用 "),s("code",[a._v("@AssembleMp")]),a._v(" 注解来配置以 "),s("code",[a._v("BaseMapper")]),a._v(" 接口的查询方法作为数据源的装配操作。这个注解会被配置解析器中的专门的注解解析器 "),s("code",[a._v("AssembleMpAnnotationHandler")]),a._v(" 解析为 "),s("code",[a._v("AssembleOperation")]),a._v("。")]),a._v(" "),s("p",[a._v("在使用时,由于可以同时指定"),s("strong",[a._v("查询的条件字段")]),a._v("和"),s("strong",[a._v("查询字段")]),a._v(",从而有四种情况:")]),a._v(" "),s("ul",[s("li",[a._v("根据默认主键查询全部字段;")]),a._v(" "),s("li",[a._v("根据默认主键查询指定字段;")]),a._v(" "),s("li",[a._v("根据指定外键查询全部字段;")]),a._v(" "),s("li",[a._v("根据指定外键查询指定字段;")])]),a._v(" "),s("p",[a._v("假设我们有一个数据库表映射对象如下:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableId")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" userName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" userAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("并且在 Spring 上下文中已经有了一个继承 "),s("code",[a._v("BaseMapper")]),a._v(" 接口的 "),s("code",[a._v("FooMapper")]),a._v(" bean,其 bean 名称默认为 "),s("code",[a._v("fooMapper")]),a._v("。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-1-根据主键查询全部字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-1-根据主键查询全部字段"}},[a._v("#")]),a._v(" 6.1.3.1.根据主键查询全部字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("当执行装配时,数据源等同于基于 "),s("code",[a._v("id")]),a._v(" 批量查询出来的 "),s("code",[a._v("Foo")]),a._v(" 对象,SQL 为 "),s("code",[a._v("select * from foo where id in ?")]),a._v("。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-2-根据主键查询指定字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-2-根据主键查询指定字段"}},[a._v("#")]),a._v(" 6.1.3.2.根据主键查询指定字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 要查询的字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select user_name AS userName, user_age AS userAge, id from foo where id in ?")]),a._v(" 这条 SQL,查询出的数据将按照 "),s("code",[a._v("Foo")]),a._v(" 中配置的主键 "),s("code",[a._v("id")]),a._v(" 进行分组。")]),a._v(" "),s("p",[s("strong",[a._v("查询字段名为实体类中对应的属性名,构建 SQL 时会自动转换为查询 SQL")]),a._v("。")]),a._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),s("p",[a._v("默认情况下,"),s("code",[a._v("crane4j")]),a._v(" 将使用被 "),s("code",[a._v("@TableId")]),a._v(" 注解标记的属性作为主键。")])]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-3-根据指定外键查询全部字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-3-根据指定外键查询全部字段"}},[a._v("#")]),a._v(" 6.1.3.3.根据指定外键查询全部字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 查询的条件字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select * from foo where user_name in ?")]),a._v(" 这条 SQL,查询出的数据将按照用户指定的 "),s("code",[a._v("userName")]),a._v(" 属性进行分组。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-4-根据指定外键查询指定字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-4-根据指定外键查询指定字段"}},[a._v("#")]),a._v(" 6.1.3.4.根据指定外键查询指定字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 要查询的字段")]),a._v("\n where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 查询的条件字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select user_age AS userAge, user_name AS userName from foo where user_name in ?")]),a._v(" 这条 SQL,查询出的数据将按照用户指定的 "),s("code",[a._v("name")]),a._v(" 属性进行分组。")]),a._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),s("p",[a._v("由于查询出的数据需要根据用户指定的外键字段进行分组,并与键值对应,因此如果用户指定了查询字段,但未包含该外键字段时,将自动在查询字段后面追加该外键字段。")])]),a._v(" "),s("h2",{attrs:{id:"_6-1-4-指定查询字段-sql"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-4-指定查询字段-sql"}},[a._v("#")]),a._v(" 6.1.4.指定查询字段 SQL")]),a._v(" "),s("p",[a._v("通常情况下,建议用户始终使用"),s("strong",[a._v("实体类中的属性名作为查询字段/查询外键")]),a._v(","),s("code",[a._v("crane4j")]),a._v(" 会借助 MP 的 "),s("code",[a._v("TableInfo")]),a._v(" 将其转换为对应的表字段 SQL。")]),a._v(" "),s("p",[a._v("然而,有时确实需要自定义查询字段的情况,因此可以直接编写自定义 SQL 作为查询字段。")]),a._v(" "),s("p",[a._v("例如,假设有以下 "),s("code",[a._v("Bean")]),a._v(":")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("FooDO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableId")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("然后装配配置如下:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("FooVO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name AS name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge AS age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("最终执行的 SQL 为:"),s("code",[a._v("select user_age AS age, user_name AS name from foo where user_name in ?")]),a._v("。")]),a._v(" "),s("div",{staticClass:"custom-block warning"},[s("p",{staticClass:"custom-block-title"},[a._v("WARNING")]),a._v(" "),s("p",[a._v("需要注意的是,该查询是基于 "),s("code",[a._v("QueryWrapper")]),a._v(" 完成的,因此在这种情况下,查询的表字段可能与用户的对象属性不一致,且无法自动设置别名。")])]),a._v(" "),s("h2",{attrs:{id:"_6-1-5-指定映射类型"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-5-指定映射类型"}},[a._v("#")]),a._v(" 6.1.5.指定映射类型")]),a._v(" "),s("p",[a._v("与方法容器类似,基于 MyBatis Plus 的查询也允许指定查询结果的一对一或一对多映射类型。例如:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("DeptEmpVO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"empMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"deptId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 根据部门 id 查询员工集合")]),a._v("\n mappingType "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[a._v("ONE_TO_MANY")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 按部门 id 进行一对多映射")]),a._v("\n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"oneToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 一对多映射处理器")]),a._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"deptNames"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 将指定部门下所有的员工名称映射到 empNames 集合")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" deptId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" empNames"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("上述示例中,使用 "),s("code",[a._v("@AssembleMp")]),a._v(" 注解指定在 "),s("code",[a._v("empMapper")]),a._v(" 中根据部门 id 查询员工集合,然后按部门 id 进行一对多映射。最后,将员工集合中的员工名称映射到 "),s("code",[a._v("DeptEmpVO")]),a._v(" 对象的 "),s("code",[a._v("empNames")]),a._v(" 集合中。")]),a._v(" "),s("p",[a._v("这样,我们可以实现多对一的映射关系。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{307:function(a,s,t){"use strict";t.r(s);var n=t(14),e=Object(n.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[a._v("#")]),a._v(" 概述")]),a._v(" "),s("p",[s("code",[a._v("crane4j")]),a._v(" 提供 "),s("code",[a._v("MybatisPlus")]),a._v(" 的扩展组件,允许基于 "),s("code",[a._v("MybatisPlus")]),a._v(" 的 "),s("code",[a._v("BaseMapper")]),a._v(" 自动构建数据源容器,以便快速的实现查询关联数据并用于填充。")]),a._v(" "),s("h2",{attrs:{id:"_6-1-1-安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-1-安装"}},[a._v("#")]),a._v(" 6.1.1.安装")]),a._v(" "),s("p",[a._v("先引入 maven 依赖:")]),a._v(" "),s("div",{staticClass:"language-xml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("\x3c!-- 先引入 crane4j-spring-boot-starter --\x3e")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("top.crane4j"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("crane4j-spring-boot-starter"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("\x3c!-- 引入 mybatis-plus --\x3e")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("com.baomidou"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("mybatis-plus-boot-starter"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n\t"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),a._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v("${last-version}"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("")])]),a._v("\n")])])]),s("p",[a._v("然后在启动类上添加 "),s("code",[a._v("@EnableCrane4j")]),a._v(" 或单独添加 "),s("code",[a._v("@EnableCrane4jMybatisPlusExtension")]),a._v(" 注解即可:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@EnableCrane4j")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@SpringBootApplication")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MbossChargeApplication")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("static")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("void")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("SpringApplication")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MbossChargeApplication")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h2",{attrs:{id:"_6-1-2-注册mapper"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-2-注册mapper"}},[a._v("#")]),a._v(" 6.1.2.注册Mapper")]),a._v(" "),s("p",[s("strong",[a._v("懒加载")])]),a._v(" "),s("p",[a._v("在 spring 环境中,用户默认不需要进行额外的操作,"),s("code",[a._v("MybatisPlusQueryContainerProvider")]),a._v(" 会在用户使用时根据 "),s("code",[a._v("beanName")]),a._v(" 自动从 spring 上下文中获得对应的 "),s("code",[a._v("Mapper")]),a._v(",并完成自动注册,即懒加载。")]),a._v(" "),s("p",[s("strong",[a._v("自动注册")])]),a._v(" "),s("p",[a._v("在 spring 环境中,用户也可以指定 "),s("code",[a._v("auto-register-mapper")]),a._v(" 为 "),s("code",[a._v("true")]),a._v(" 开启自动注册,相关配置如下:")]),a._v(" "),s("div",{staticClass:"language-yml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-yml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("crane4j")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("mybatis-plus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("auto-register-mapper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token boolean important"}},[a._v("true")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 启动自动注册")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 仅注册指定 Mapper")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("excludes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 仅排除指定 Mapper")]),a._v("\n")])])]),s("p",[a._v("在开启自动注册的情况下,spring 上下文中任何符合 "),s("code",[a._v("includes")]),a._v(" 与 "),s("code",[a._v("excludes")]),a._v(" 规则的 "),s("code",[a._v("Mapper")]),a._v(" 都会被注册。")]),a._v(" "),s("p",[s("strong",[a._v("手动注册")])]),a._v(" "),s("p",[a._v("用户也可以获取 "),s("code",[a._v("MybatisPlusQueryContainerProvider")]),a._v(" 进行手动注册:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MybatisPlusQueryContainerProvider")]),a._v(" register "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("SpringUtil")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("getBean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MybatisPlusQueryContainerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nregister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("registerRepository")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xxxMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" xxxMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("h2",{attrs:{id:"_6-1-3-基本使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-基本使用"}},[a._v("#")]),a._v(" 6.1.3.基本使用")]),a._v(" "),s("p",[a._v("用户可以使用 "),s("code",[a._v("@AssembleMp")]),a._v(" 注解来配置以 "),s("code",[a._v("BaseMapper")]),a._v(" 接口的查询方法作为数据源的装配操作。这个注解会被配置解析器中的专门的注解解析器 "),s("code",[a._v("AssembleMpAnnotationHandler")]),a._v(" 解析为 "),s("code",[a._v("AssembleOperation")]),a._v("。")]),a._v(" "),s("p",[a._v("在使用时,由于可以同时指定"),s("strong",[a._v("查询的条件字段")]),a._v("和"),s("strong",[a._v("查询字段")]),a._v(",从而有四种情况:")]),a._v(" "),s("ul",[s("li",[a._v("根据默认主键查询全部字段;")]),a._v(" "),s("li",[a._v("根据默认主键查询指定字段;")]),a._v(" "),s("li",[a._v("根据指定外键查询全部字段;")]),a._v(" "),s("li",[a._v("根据指定外键查询指定字段;")])]),a._v(" "),s("p",[a._v("假设我们有一个数据库表映射对象如下:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableId")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" userName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" userAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("并且在 Spring 上下文中已经有了一个继承 "),s("code",[a._v("BaseMapper")]),a._v(" 接口的 "),s("code",[a._v("FooMapper")]),a._v(" bean,其 bean 名称默认为 "),s("code",[a._v("fooMapper")]),a._v("。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-1-根据主键查询全部字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-1-根据主键查询全部字段"}},[a._v("#")]),a._v(" 6.1.3.1.根据主键查询全部字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Foo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("当执行装配时,数据源等同于基于 "),s("code",[a._v("id")]),a._v(" 批量查询出来的 "),s("code",[a._v("Foo")]),a._v(" 对象,SQL 为 "),s("code",[a._v("select * from foo where id in ?")]),a._v("。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-2-根据主键查询指定字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-2-根据主键查询指定字段"}},[a._v("#")]),a._v(" 6.1.3.2.根据主键查询指定字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 要查询的字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select user_name AS userName, user_age AS userAge, id from foo where id in ?")]),a._v(" 这条 SQL,查询出的数据将按照 "),s("code",[a._v("Foo")]),a._v(" 中配置的主键 "),s("code",[a._v("id")]),a._v(" 进行分组。")]),a._v(" "),s("p",[s("strong",[a._v("查询字段名为实体类中对应的属性名,构建 SQL 时会自动转换为查询 SQL")]),a._v("。")]),a._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),s("p",[a._v("默认情况下,"),s("code",[a._v("crane4j")]),a._v(" 将使用被 "),s("code",[a._v("@TableId")]),a._v(" 注解标记的属性作为主键。")])]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-3-根据指定外键查询全部字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-3-根据指定外键查询全部字段"}},[a._v("#")]),a._v(" 6.1.3.3.根据指定外键查询全部字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 查询的条件字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select * from foo where user_name in ?")]),a._v(" 这条 SQL,查询出的数据将按照用户指定的 "),s("code",[a._v("userName")]),a._v(" 属性进行分组。")]),a._v(" "),s("h3",{attrs:{id:"_6-1-3-4-根据指定外键查询指定字段"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-3-4-根据指定外键查询指定字段"}},[a._v("#")]),a._v(" 6.1.3.4.根据指定外键查询指定字段")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 要查询的字段")]),a._v("\n where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userName"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 查询的条件字段")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])])]),s("p",[a._v("上述配置相当于使用 "),s("code",[a._v("QueryWrapper")]),a._v(" 构建并执行了 "),s("code",[a._v("select user_age AS userAge, user_name AS userName from foo where user_name in ?")]),a._v(" 这条 SQL,查询出的数据将按照用户指定的 "),s("code",[a._v("name")]),a._v(" 属性进行分组。")]),a._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),s("p",[a._v("由于查询出的数据需要根据用户指定的外键字段进行分组,并与键值对应,因此如果用户指定了查询字段,但未包含该外键字段时,将自动在查询字段后面追加该外键字段。")])]),a._v(" "),s("h2",{attrs:{id:"_6-1-4-指定查询字段-sql"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-4-指定查询字段-sql"}},[a._v("#")]),a._v(" 6.1.4.指定查询字段 SQL")]),a._v(" "),s("p",[a._v("通常情况下,建议用户始终使用"),s("strong",[a._v("实体类中的属性名作为查询字段/查询外键")]),a._v(","),s("code",[a._v("crane4j")]),a._v(" 会借助 MP 的 "),s("code",[a._v("TableInfo")]),a._v(" 将其转换为对应的表字段 SQL。")]),a._v(" "),s("p",[a._v("然而,有时确实需要自定义查询字段的情况,因此可以直接编写自定义 SQL 作为查询字段。")]),a._v(" "),s("p",[a._v("例如,假设有以下 "),s("code",[a._v("Bean")]),a._v(":")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("FooDO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableId")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@TableField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("然后装配配置如下:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("FooVO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fooMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n selects "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"user_name AS name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"userAge AS age"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),a._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("最终执行的 SQL 为:"),s("code",[a._v("select user_age AS age, user_name AS name from foo where user_name in ?")]),a._v("。")]),a._v(" "),s("div",{staticClass:"custom-block warning"},[s("p",{staticClass:"custom-block-title"},[a._v("WARNING")]),a._v(" "),s("p",[a._v("需要注意的是,该查询是基于 "),s("code",[a._v("QueryWrapper")]),a._v(" 完成的,因此在这种情况下,查询的表字段可能与用户的对象属性不一致,且无法自动设置别名。")])]),a._v(" "),s("h2",{attrs:{id:"_6-1-5-指定映射类型"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-5-指定映射类型"}},[a._v("#")]),a._v(" 6.1.5.指定映射类型")]),a._v(" "),s("p",[a._v("与方法容器类似,基于 MyBatis Plus 的查询也允许指定查询结果的一对一或一对多映射类型。例如:")]),a._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("public")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("class")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("DeptEmpVO")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@AssembleMp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("\n mapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"empMapper"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" where "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"deptId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 根据部门 id 查询员工集合")]),a._v("\n mappingType "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MappingType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[a._v("ONE_TO_MANY")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 按部门 id 进行一对多映射")]),a._v("\n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"oneToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 一对多映射处理器")]),a._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[a._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"deptNames"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// 将指定部门下所有的员工名称映射到 empNames 集合")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Integer")]),a._v(" deptId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("private")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(">")])]),a._v(" empNames"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("p",[a._v("上述示例中,使用 "),s("code",[a._v("@AssembleMp")]),a._v(" 注解指定在 "),s("code",[a._v("empMapper")]),a._v(" 中根据部门 id 查询员工集合,然后按部门 id 进行一对多映射。最后,将员工集合中的员工名称映射到 "),s("code",[a._v("DeptEmpVO")]),a._v(" 对象的 "),s("code",[a._v("empNames")]),a._v(" 集合中。")]),a._v(" "),s("p",[a._v("这样,我们可以实现多对一的映射关系。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/38.cff412fe.js b/docs/assets/js/38.17953578.js similarity index 96% rename from docs/assets/js/38.cff412fe.js rename to docs/assets/js/38.17953578.js index cc8cb21f..c4e2badd 100644 --- a/docs/assets/js/38.cff412fe.js +++ b/docs/assets/js/38.17953578.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{311:function(t,e,a){"use strict";a.r(e);var s=a(14),o=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"概述"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),e("p",[t._v("在 "),e("code",[t._v("crane4j")]),t._v(" 中,根据对象 A 的 key 值获取对象 B,并将 B 的属性映射到 A 上的过程称为"),e("strong",[t._v("装配")]),t._v(",当处理嵌套结构的对象时,将嵌套的对象取出并平铺,重复该过程直到所有对象都平铺的过程称为"),e("strong",[t._v("拆卸")]),t._v("。")]),t._v(" "),e("p",[t._v("在一个类中,可以针对特定的 key 属性或 key 方法声明一个或多个装配/拆卸操作。配置解析器将这些声明解析为多个 "),e("code",[t._v("AssembleOperation")]),t._v(" 或 "),e("code",[t._v("DisassembleOperation")]),t._v(" 对象,每个对象代表一个具体的装配操作或拆卸操作。最终,类的基本信息和所有操作对象都会聚合到一个 "),e("code",[t._v("BeanOperations")]),t._v(" 对象中。")]),t._v(" "),e("p",[t._v("执行过程中,操作执行器根据 "),e("code",[t._v("BeanOperations")]),t._v(" 对象完成特定类型对象的填充。通常,操作执行器首先执行所有的拆卸操作,将对象平铺开来,然后按照特定的分组方式的顺序执行全部装配操作。")]),t._v(" "),e("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230220180719411.png",alt:"image-20230220180719411"}})])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{318:function(t,e,a){"use strict";a.r(e);var s=a(14),o=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"概述"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),e("p",[t._v("在 "),e("code",[t._v("crane4j")]),t._v(" 中,根据对象 A 的 key 值获取对象 B,并将 B 的属性映射到 A 上的过程称为"),e("strong",[t._v("装配")]),t._v(",当处理嵌套结构的对象时,将嵌套的对象取出并平铺,重复该过程直到所有对象都平铺的过程称为"),e("strong",[t._v("拆卸")]),t._v("。")]),t._v(" "),e("p",[t._v("在一个类中,可以针对特定的 key 属性或 key 方法声明一个或多个装配/拆卸操作。配置解析器将这些声明解析为多个 "),e("code",[t._v("AssembleOperation")]),t._v(" 或 "),e("code",[t._v("DisassembleOperation")]),t._v(" 对象,每个对象代表一个具体的装配操作或拆卸操作。最终,类的基本信息和所有操作对象都会聚合到一个 "),e("code",[t._v("BeanOperations")]),t._v(" 对象中。")]),t._v(" "),e("p",[t._v("执行过程中,操作执行器根据 "),e("code",[t._v("BeanOperations")]),t._v(" 对象完成特定类型对象的填充。通常,操作执行器首先执行所有的拆卸操作,将对象平铺开来,然后按照特定的分组方式的顺序执行全部装配操作。")]),t._v(" "),e("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230220180719411.png",alt:"image-20230220180719411"}})])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/4.fce9ea21.js b/docs/assets/js/4.e00196de.js similarity index 88% rename from docs/assets/js/4.fce9ea21.js rename to docs/assets/js/4.e00196de.js index a084b6a3..1c29a4ad 100644 --- a/docs/assets/js/4.fce9ea21.js +++ b/docs/assets/js/4.e00196de.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{255:function(t,e,a){},278:function(t,e,a){"use strict";a(255)},282:function(t,e,a){"use strict";a.r(e);var s={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(278),a(14)),n=Object(i.a)(s,(function(){return(0,this._self._c)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{255:function(t,e,a){},278:function(t,e,a){"use strict";a(255)},283:function(t,e,a){"use strict";a.r(e);var s={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(278),a(14)),n=Object(i.a)(s,(function(){return(0,this._self._c)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/40.2bff2f24.js b/docs/assets/js/40.ba37a38d.js similarity index 99% rename from docs/assets/js/40.2bff2f24.js rename to docs/assets/js/40.ba37a38d.js index 37316ed9..1f44ce8d 100644 --- a/docs/assets/js/40.2bff2f24.js +++ b/docs/assets/js/40.ba37a38d.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{313:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("属性/字段映射是装配操作的一部分,用于描述将数据源对象的哪些字段的值填充到目标对象的哪些字段上。")]),t._v(" "),s("p",[t._v("在装配操作中,我们可以使用 "),s("code",[t._v("@Mapping")]),t._v(" 注解来配置字段映射,以指定要进行映射的属性和对应关系。"),s("code",[t._v("@Mapping")]),t._v(" 注解包含以下信息:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("src")]),t._v(" 属性:指定要从数据源对象中获取值的属性名。")]),t._v(" "),s("li",[s("code",[t._v("ref")]),t._v(" 属性:指定要填充值的目标属性名。")])]),t._v(" "),s("p",[t._v("通过在目标对象的字段上添加 "),s("code",[t._v("@Mapping")]),t._v(" 注解,并设置对应的 "),s("code",[t._v("src")]),t._v("和 "),s("code",[t._v("ref")]),t._v(" 属性,我们告知装配操作处理器哪些属性需要进行映射以及属性之间的对应关系,不通的 "),s("code",[t._v("src")]),t._v(" 和 "),s("code",[t._v("ref")]),t._v(" 搭配将会产生不同的效果。")]),t._v(" "),s("img",{staticStyle:{zoom:"50%"},attrs:{src:"https://img.xiajibagao.top/image-20230220182129822.png",alt:"image-20230220182129822"}}),t._v(" "),s("h2",{attrs:{id:"_3-2-1-将属性映射到属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-1-将属性映射到属性"}},[t._v("#")]),t._v(" 3.2.1.将属性映射到属性")]),t._v(" "),s("p",[t._v("字段映射配置类似于 MapStruct,在使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解声明装配操作时,我们可以在 "),s("code",[t._v("props")]),t._v(" 中属性使用 "),s("code",[t._v("@Mapping")]),t._v(" 注解配置属性映射。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.studentName -> studentVO.name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.studentClassName -> studentVO.className")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,我们通过"),s("code",[t._v("@Assemble")]),t._v("注解指定了数据源容器和字段映射。其中,"),s("code",[t._v("props")]),t._v(" 属性中使用了 "),s("code",[t._v("@Mapping")]),t._v(" 注解配置了两个映射属性,分别将"),s("code",[t._v("Student.studentName")]),t._v("映射到"),s("code",[t._v("StudentVO.name")]),t._v(",将"),s("code",[t._v("Student.studentClassName")]),t._v("映射到"),s("code",[t._v("StudentVO.className")]),t._v("。")]),t._v(" "),s("p",[s("strong",[t._v("同名属性")])]),t._v(" "),s("p",[t._v("另外,如果 "),s("code",[t._v("src")]),t._v(" 和 "),s("code",[t._v("ref")]),t._v(" 指定的字段名称相同,可以直接在"),s("code",[t._v("value")]),t._v("中同时指定。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.name -> studentVO.name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("strong",[t._v("特殊对象支持")])]),t._v(" "),s("p",[t._v("数据源对象可以是 "),s("code",[t._v("Map")]),t._v(" 集合,此时 "),s("code",[t._v("src")]),t._v(" 即为要获取的键值的 "),s("code",[t._v("key")]),t._v(",而如果是对象(包括枚举)则为要获取的属性值的名称,这种情况下用户需要确保对应的属性存在 "),s("code",[t._v("setter")]),t._v(" 和 "),s("code",[t._v("getter")]),t._v(" 方法。")]),t._v(" "),s("p",[s("strong",[t._v("自动类型转换")])]),t._v(" "),s("p",[t._v("字段映射的实现基于反射工厂 "),s("code",[t._v("PropertyOperator")]),t._v(" 实现,默认使用的实现类支持一定程度的自动类型转换,具体参见 "),s("code",[t._v("ConverterManager")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-2-将对象映射到属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-2-将对象映射到属性"}},[t._v("#")]),t._v(" 3.2.2.将对象映射到属性")]),t._v(" "),s("p",[t._v("当在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中不指定源字段 "),s("code",[t._v("src")]),t._v(" 时,表示直接将整个数据源对象作为映射值。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student -> studentVO.student")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("id")]),t._v(" 查找到 "),s("code",[t._v("Student")]),t._v(" 对象后,直接将该 "),s("code",[t._v("Student")]),t._v(" 对象赋值给"),s("code",[t._v("StudentVO.student")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("这种配置通常适用于对象的组装,或者当数据源对象本身就是某个字典值或枚举值的情况。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-3-将值映射到键属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-3-将值映射到键属性"}},[t._v("#")]),t._v(" 3.2.3.将值映射到键属性")]),t._v(" "),s("p",[t._v("当在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中不指定引用字段 "),s("code",[t._v("ref")]),t._v(" 时,表示直接将映射值映射到 "),s("code",[t._v("key")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// gender.name -> studentVO.sex")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("StudentVO.sex")]),t._v(" 查找到性别字典对象 "),s("code",[t._v("Gender")]),t._v(" 后,将其对应的 "),s("code",[t._v("Gender.name")]),t._v(" 映射回 "),s("code",[t._v("StudentVO.sex")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("这种配置适用于将字典值或枚举值映射回目标对象的字段上。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-4-批量映射"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-4-批量映射"}},[t._v("#")]),t._v(" 3.2.4.批量映射")]),t._v(" "),s("p",[t._v("在一些情况下下,从数据源容器获得的一个键值将对应一批数据源对象(比如一对多或者多对多装配)。在这种情况下,字段映射将变为"),s("strong",[t._v("批量映射")]),t._v("模式")]),t._v(" "),s("p",[t._v("具体而言,对于集合或数组中的每个数据源对象,我们会从中获取指定的 "),s("code",[t._v("src")]),t._v(" 属性值,并将所有属性值组装为集合,然后将该集合赋值给目标对象中的 "),s("code",[t._v("ref")]),t._v(" 属性。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacher"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"manyToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [teacher, teacher...] -> [teacher.name, teacher.name...] -> studentVO.teacherNames")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherNames"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 以逗号分隔的字符串,例如:1, 2, 3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teacherNames"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("teacherIds")]),t._v(" 字段字符串中通过逗号分隔的多个键值,查询关联的多个 "),s("code",[t._v("Teacher")]),t._v(" 对象,然后将 "),s("code",[t._v("Teacher")]),t._v(" 对象集合的 "),s("code",[t._v("name")]),t._v(" 属性映射为 "),s("code",[t._v("List")]),t._v(" 并赋值给 "),s("code",[t._v("StudentVO.teacherNames")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("该字段映射遵循普通字段映射的语义,例如对象映射:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacher"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"manyToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teachers"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teacherIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 也可以直接是集合或者数组")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Teacher")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teachers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在批量映射的情况下,返回的对象可以是数据源对象或数据源对象的属性集合。")]),t._v(" "),s("div",{staticClass:"custom-block warning"},[s("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),s("ul",[s("li",[t._v("如果用户传入的字符串是 "),s("code",[t._v("id1, id2, id3...")]),t._v(" 这样的格式,分割后的值默认保持为 "),s("code",[t._v("String")]),t._v(" 类型。用户需要确保目标容器能够接受 "),s("code",[t._v("String")]),t._v(" 类型的键;")]),t._v(" "),s("li",[t._v("如果分隔符不是逗号 "),s("code",[t._v(",")]),t._v(",或者有其他拆分规则,用户可以为 "),s("code",[t._v("ManyToManyAssembleOperationHandler")]),t._v(" 设置自定义的字符串分割器;")])])]),t._v(" "),s("h2",{attrs:{id:"_3-2-5-映射模板"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-5-映射模板"}},[t._v("#")]),t._v(" 3.2.5.映射模板")]),t._v(" "),s("p",[t._v("为了保持代码的整洁性,我们可以将字段映射配置抽取为独立的模板。")]),t._v(" "),s("p",[t._v("例如,给定以下字段配置:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("我们可以创建一个模板类 "),s("code",[t._v("StudentMappingTemplate")]),t._v(",将 "),s("code",[t._v("props")]),t._v(" 中的映射配置移到模板类中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@MappingTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentMappingTemplate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("然后,在 "),s("code",[t._v("@Assemble")]),t._v(" 注解中使用 "),s("code",[t._v("propTemplates")]),t._v(" 引入模板:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n propTemplates "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentMappingTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" teacherAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("通过模板引入的字段映射配置与通过 "),s("code",[t._v("@Assemble.props")]),t._v(" 声明的配置效果相同,并且两者可以同时存在。")]),t._v(" "),s("p",[t._v("字段映射规则按照就近原则执行。即离 "),s("code",[t._v("StudentVO")]),t._v(" 越近,且排序靠前的字段优先完成映射,后面的映射字段会覆盖已有的值。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-6-链式操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-6-链式操作符"}},[t._v("#")]),t._v(" 3.2.6.链式操作符")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 支持在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中,通过类似 js 的链式操作符的方式来访问及设置嵌套对象的属性。")]),t._v(" "),s("p",[t._v("例如,我们有一个 "),s("code",[t._v("Foo")]),t._v(" 类如下:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"nested.name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NestedFoo")]),t._v(" nested"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NestedFoo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("我们声明了一个装配操作,假设 "),s("code",[t._v("foo")]),t._v(" 容器返回的数据源对象是 "),s("code",[t._v("Foo")]),t._v(",则上述示例表示,获取到 "),s("code",[t._v("Foo")]),t._v(" 对象后,将 "),s("code",[t._v("Foo.name")]),t._v(" 映射到 "),s("code",[t._v("FooVO")]),t._v(" 对象中 "),s("code",[t._v("nested")]),t._v(" 属性中的嵌套对象 "),s("code",[t._v("NestedFoo")]),t._v(" 的 "),s("code",[t._v("name")]),t._v(" 属性。")]),t._v(" "),s("p",[t._v("除了属性映射外,该功能理论上适用于"),s("strong",[t._v("所有具备属性访问功能的配置项")]),t._v(",包括但不限于:")]),t._v(" "),s("ul",[s("li",[t._v("类级别的配置注解,例如 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("key")]),t._v(" 属性;")]),t._v(" "),s("li",[t._v("自动填充注解 "),s("code",[t._v("@AutoOperate")]),t._v(" 中的 "),s("code",[t._v("on")]),t._v(" 属性;")]),t._v(" "),s("li",[t._v("方法数据源容器配置中对方法调用结果进行分组的 "),s("code",[t._v("key")]),t._v(" 字段,例如 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的 "),s("code",[t._v("resultKey")]),t._v(" 属性;")])]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("该功能是通过 "),s("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(" 类实现的。如果用户替换了默认的 "),s("code",[t._v("PropertyOperator")]),t._v(",则需要手动使用 "),s("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(" 对用户的实现进行包装。")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{316:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("属性/字段映射是装配操作的一部分,用于描述将数据源对象的哪些字段的值填充到目标对象的哪些字段上。")]),t._v(" "),s("p",[t._v("在装配操作中,我们可以使用 "),s("code",[t._v("@Mapping")]),t._v(" 注解来配置字段映射,以指定要进行映射的属性和对应关系。"),s("code",[t._v("@Mapping")]),t._v(" 注解包含以下信息:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("src")]),t._v(" 属性:指定要从数据源对象中获取值的属性名。")]),t._v(" "),s("li",[s("code",[t._v("ref")]),t._v(" 属性:指定要填充值的目标属性名。")])]),t._v(" "),s("p",[t._v("通过在目标对象的字段上添加 "),s("code",[t._v("@Mapping")]),t._v(" 注解,并设置对应的 "),s("code",[t._v("src")]),t._v("和 "),s("code",[t._v("ref")]),t._v(" 属性,我们告知装配操作处理器哪些属性需要进行映射以及属性之间的对应关系,不通的 "),s("code",[t._v("src")]),t._v(" 和 "),s("code",[t._v("ref")]),t._v(" 搭配将会产生不同的效果。")]),t._v(" "),s("img",{staticStyle:{zoom:"50%"},attrs:{src:"https://img.xiajibagao.top/image-20230220182129822.png",alt:"image-20230220182129822"}}),t._v(" "),s("h2",{attrs:{id:"_3-2-1-将属性映射到属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-1-将属性映射到属性"}},[t._v("#")]),t._v(" 3.2.1.将属性映射到属性")]),t._v(" "),s("p",[t._v("字段映射配置类似于 MapStruct,在使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解声明装配操作时,我们可以在 "),s("code",[t._v("props")]),t._v(" 中属性使用 "),s("code",[t._v("@Mapping")]),t._v(" 注解配置属性映射。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.studentName -> studentVO.name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.studentClassName -> studentVO.className")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,我们通过"),s("code",[t._v("@Assemble")]),t._v("注解指定了数据源容器和字段映射。其中,"),s("code",[t._v("props")]),t._v(" 属性中使用了 "),s("code",[t._v("@Mapping")]),t._v(" 注解配置了两个映射属性,分别将"),s("code",[t._v("Student.studentName")]),t._v("映射到"),s("code",[t._v("StudentVO.name")]),t._v(",将"),s("code",[t._v("Student.studentClassName")]),t._v("映射到"),s("code",[t._v("StudentVO.className")]),t._v("。")]),t._v(" "),s("p",[s("strong",[t._v("同名属性")])]),t._v(" "),s("p",[t._v("另外,如果 "),s("code",[t._v("src")]),t._v(" 和 "),s("code",[t._v("ref")]),t._v(" 指定的字段名称相同,可以直接在"),s("code",[t._v("value")]),t._v("中同时指定。例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student.name -> studentVO.name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("strong",[t._v("特殊对象支持")])]),t._v(" "),s("p",[t._v("数据源对象可以是 "),s("code",[t._v("Map")]),t._v(" 集合,此时 "),s("code",[t._v("src")]),t._v(" 即为要获取的键值的 "),s("code",[t._v("key")]),t._v(",而如果是对象(包括枚举)则为要获取的属性值的名称,这种情况下用户需要确保对应的属性存在 "),s("code",[t._v("setter")]),t._v(" 和 "),s("code",[t._v("getter")]),t._v(" 方法。")]),t._v(" "),s("p",[s("strong",[t._v("自动类型转换")])]),t._v(" "),s("p",[t._v("字段映射的实现基于反射工厂 "),s("code",[t._v("PropertyOperator")]),t._v(" 实现,默认使用的实现类支持一定程度的自动类型转换,具体参见 "),s("code",[t._v("ConverterManager")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-2-将对象映射到属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-2-将对象映射到属性"}},[t._v("#")]),t._v(" 3.2.2.将对象映射到属性")]),t._v(" "),s("p",[t._v("当在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中不指定源字段 "),s("code",[t._v("src")]),t._v(" 时,表示直接将整个数据源对象作为映射值。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// student -> studentVO.student")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("id")]),t._v(" 查找到 "),s("code",[t._v("Student")]),t._v(" 对象后,直接将该 "),s("code",[t._v("Student")]),t._v(" 对象赋值给"),s("code",[t._v("StudentVO.student")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("这种配置通常适用于对象的组装,或者当数据源对象本身就是某个字典值或枚举值的情况。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-3-将值映射到键属性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-3-将值映射到键属性"}},[t._v("#")]),t._v(" 3.2.3.将值映射到键属性")]),t._v(" "),s("p",[t._v("当在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中不指定引用字段 "),s("code",[t._v("ref")]),t._v(" 时,表示直接将映射值映射到 "),s("code",[t._v("key")]),t._v(" 字段上。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"gender"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// gender.name -> studentVO.sex")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("StudentVO.sex")]),t._v(" 查找到性别字典对象 "),s("code",[t._v("Gender")]),t._v(" 后,将其对应的 "),s("code",[t._v("Gender.name")]),t._v(" 映射回 "),s("code",[t._v("StudentVO.sex")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("这种配置适用于将字典值或枚举值映射回目标对象的字段上。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-4-批量映射"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-4-批量映射"}},[t._v("#")]),t._v(" 3.2.4.批量映射")]),t._v(" "),s("p",[t._v("在一些情况下下,从数据源容器获得的一个键值将对应一批数据源对象(比如一对多或者多对多装配)。在这种情况下,字段映射将变为"),s("strong",[t._v("批量映射")]),t._v("模式")]),t._v(" "),s("p",[t._v("具体而言,对于集合或数组中的每个数据源对象,我们会从中获取指定的 "),s("code",[t._v("src")]),t._v(" 属性值,并将所有属性值组装为集合,然后将该集合赋值给目标对象中的 "),s("code",[t._v("ref")]),t._v(" 属性。")]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacher"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"manyToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [teacher, teacher...] -> [teacher.name, teacher.name...] -> studentVO.teacherNames")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherNames"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 以逗号分隔的字符串,例如:1, 2, 3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teacherNames"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("上述示例中,根据 "),s("code",[t._v("teacherIds")]),t._v(" 字段字符串中通过逗号分隔的多个键值,查询关联的多个 "),s("code",[t._v("Teacher")]),t._v(" 对象,然后将 "),s("code",[t._v("Teacher")]),t._v(" 对象集合的 "),s("code",[t._v("name")]),t._v(" 属性映射为 "),s("code",[t._v("List")]),t._v(" 并赋值给 "),s("code",[t._v("StudentVO.teacherNames")]),t._v(" 字段。")]),t._v(" "),s("p",[t._v("该字段映射遵循普通字段映射的语义,例如对象映射:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacher"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n handler "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"manyToManyAssembleOperationHandler"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teachers"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teacherIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 也可以直接是集合或者数组")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Teacher")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" teachers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在批量映射的情况下,返回的对象可以是数据源对象或数据源对象的属性集合。")]),t._v(" "),s("div",{staticClass:"custom-block warning"},[s("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),s("ul",[s("li",[t._v("如果用户传入的字符串是 "),s("code",[t._v("id1, id2, id3...")]),t._v(" 这样的格式,分割后的值默认保持为 "),s("code",[t._v("String")]),t._v(" 类型。用户需要确保目标容器能够接受 "),s("code",[t._v("String")]),t._v(" 类型的键;")]),t._v(" "),s("li",[t._v("如果分隔符不是逗号 "),s("code",[t._v(",")]),t._v(",或者有其他拆分规则,用户可以为 "),s("code",[t._v("ManyToManyAssembleOperationHandler")]),t._v(" 设置自定义的字符串分割器;")])])]),t._v(" "),s("h2",{attrs:{id:"_3-2-5-映射模板"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-5-映射模板"}},[t._v("#")]),t._v(" 3.2.5.映射模板")]),t._v(" "),s("p",[t._v("为了保持代码的整洁性,我们可以将字段映射配置抽取为独立的模板。")]),t._v(" "),s("p",[t._v("例如,给定以下字段配置:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("我们可以创建一个模板类 "),s("code",[t._v("StudentMappingTemplate")]),t._v(",将 "),s("code",[t._v("props")]),t._v(" 中的映射配置移到模板类中:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@MappingTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentClassName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"className"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherName"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentMappingTemplate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("然后,在 "),s("code",[t._v("@Assemble")]),t._v(" 注解中使用 "),s("code",[t._v("propTemplates")]),t._v(" 引入模板:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"studentTeacherAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"teacherAge"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n propTemplates "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StudentMappingTemplate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" className"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" teacherName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" teacherAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("通过模板引入的字段映射配置与通过 "),s("code",[t._v("@Assemble.props")]),t._v(" 声明的配置效果相同,并且两者可以同时存在。")]),t._v(" "),s("p",[t._v("字段映射规则按照就近原则执行。即离 "),s("code",[t._v("StudentVO")]),t._v(" 越近,且排序靠前的字段优先完成映射,后面的映射字段会覆盖已有的值。")]),t._v(" "),s("h2",{attrs:{id:"_3-2-6-链式操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-6-链式操作符"}},[t._v("#")]),t._v(" 3.2.6.链式操作符")]),t._v(" "),s("p",[s("code",[t._v("crane4j")]),t._v(" 支持在 "),s("code",[t._v("@Mapping")]),t._v(" 注解中,通过类似 js 的链式操作符的方式来访问及设置嵌套对象的属性。")]),t._v(" "),s("p",[t._v("例如,我们有一个 "),s("code",[t._v("Foo")]),t._v(" 类如下:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooVO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("src "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"nested.name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NestedFoo")]),t._v(" nested"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NestedFoo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("我们声明了一个装配操作,假设 "),s("code",[t._v("foo")]),t._v(" 容器返回的数据源对象是 "),s("code",[t._v("Foo")]),t._v(",则上述示例表示,获取到 "),s("code",[t._v("Foo")]),t._v(" 对象后,将 "),s("code",[t._v("Foo.name")]),t._v(" 映射到 "),s("code",[t._v("FooVO")]),t._v(" 对象中 "),s("code",[t._v("nested")]),t._v(" 属性中的嵌套对象 "),s("code",[t._v("NestedFoo")]),t._v(" 的 "),s("code",[t._v("name")]),t._v(" 属性。")]),t._v(" "),s("p",[t._v("除了属性映射外,该功能理论上适用于"),s("strong",[t._v("所有具备属性访问功能的配置项")]),t._v(",包括但不限于:")]),t._v(" "),s("ul",[s("li",[t._v("类级别的配置注解,例如 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("key")]),t._v(" 属性;")]),t._v(" "),s("li",[t._v("自动填充注解 "),s("code",[t._v("@AutoOperate")]),t._v(" 中的 "),s("code",[t._v("on")]),t._v(" 属性;")]),t._v(" "),s("li",[t._v("方法数据源容器配置中对方法调用结果进行分组的 "),s("code",[t._v("key")]),t._v(" 字段,例如 "),s("code",[t._v("@ContainerMethod")]),t._v(" 注解的 "),s("code",[t._v("resultKey")]),t._v(" 属性;")])]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("该功能是通过 "),s("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(" 类实现的。如果用户替换了默认的 "),s("code",[t._v("PropertyOperator")]),t._v(",则需要手动使用 "),s("code",[t._v("ChainAccessiblePropertyOperator")]),t._v(" 对用户的实现进行包装。")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/41.e081aa37.js b/docs/assets/js/41.0fefdfe5.js similarity index 99% rename from docs/assets/js/41.e081aa37.js rename to docs/assets/js/41.0fefdfe5.js index 2a590a4c..7f02a8f8 100644 --- a/docs/assets/js/41.e081aa37.js +++ b/docs/assets/js/41.0fefdfe5.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{319:function(s,a,t){"use strict";t.r(a);var n=t(14),e=Object(n.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),a("p",[s._v("装配操作处理器 "),a("code",[s._v("AssembleOperateHandler")]),s._v(" 在整个装配过程中负责实际的属性读写操作,类似于 Jackson 中的序列化器("),a("code",[s._v("Serializer")]),s._v(")和反序列化器("),a("code",[s._v("Deserializer")]),s._v(")。与 Jackson 类似,如果我们需要处理特殊数据结构或具有特殊填充逻辑的 JavaBean,就需要更换不同的装配操作处理器。")]),s._v(" "),a("p",[s._v("有三种处理器的实现:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("OneToOneAssembleOperationHandler")]),s._v(":一对一装配操作处理器,也是默认的处理器;")]),s._v(" "),a("li",[a("code",[s._v("OneToManyAssembleOperationHandler")]),s._v(":一对多装配操作处理器;")]),s._v(" "),a("li",[a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(":多对多装配操作处理器;")])]),s._v(" "),a("p",[s._v("与其他组件一样,用户也可以实现 "),a("code",[s._v("AssembleOperationHandler")]),s._v(" 接口,并将其声明为 Spring 上下文中的一个组件,以实现自动注册,或者手动获取全局配置类进行注册。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-1-使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-1-使用"}},[s._v("#")]),s._v(" 3.2.1.使用")]),s._v(" "),a("p",[s._v("用户可以在 "),a("code",[s._v("@Assemble")]),s._v(" 注解的 "),a("code",[s._v("handler")]),s._v(" 属性或 "),a("code",[s._v("handlerType")]),s._v(" 属性中指定要使用的处理器。例如:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"oneToOneAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" alias"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("默认情况下,将会使用一对一装配处理器执行操作,即一个 "),a("code",[s._v("key")]),s._v(" 值只对应一个数据源对象。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-2-一对多装配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-2-一对多装配"}},[s._v("#")]),s._v(" 3.2.2.一对多装配")]),s._v(" "),a("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230320105459223.png",alt:"image-20230320105459223"}}),s._v(" "),a("p",[s._v("在一对多的情况下,一个属性对应多个数据源对象,即从数据源容器中查询数据时,一个键(key)可以查出一个集合或数组的情况。")]),s._v(" "),a("p",[s._v("例如,我们有一个名为 "),a("code",[s._v("customer")]),s._v(" 的容器,可以根据客户 id 查询客户,并返回按客户组别 id 分组的 "),a("code",[s._v("Map")]),s._v(" 集合:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 根据ID查询客户,返回的数据按客户组别ID分组")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" customerContainer "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("LambdaContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ids "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" customerService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("listByIds")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ids"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("stream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("groupBy")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("CustomerDO")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getGroupId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("现在,我们可以借助一对多装配处理器,批量提取数据源对象的属性,并将其赋值给目标对象的指定属性:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("CustomerVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"oneToManyAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customerNames"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" customerNames"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,我们根据 id 集合获取按客户组别ID分组的客户集合,并提取 "),a("code",[s._v("CustomerDO.name")]),s._v(" 作为集合,然后赋值给 "),a("code",[s._v("CustomerVO.customerNames")]),s._v("。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-3-多对多装配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-3-多对多装配"}},[s._v("#")]),s._v(" 3.2.3.多对多装配")]),s._v(" "),a("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230320105521429.png",alt:"image-20230320105521429"}}),s._v(" "),a("p",[s._v("在多对多的情况下,多个键(key)对应多个数据源对象,实际场景中,比较常见的情况有三种:")]),s._v(" "),a("ul",[a("li",[s._v("键字段是按特定分隔符拼接的字符串;")]),s._v(" "),a("li",[s._v("建字段是集合类型;")]),s._v(" "),a("li",[s._v("建字段是数组类型;")])]),s._v(" "),a("p",[s._v("例如,假设存在以下键字段类型:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" idStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 键字段为按分隔符拼接的字符串,例如:"a, b, c"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Set")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" idList"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 键字段为集合,例如:[a, b, c]")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" idArray"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 键字段为数组,例如:[a, b, c]")]),s._v("\n")])])]),a("p",[s._v("针对多个键字段映射,需要使用特定的装配操作处理器 "),a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(":")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StudentVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacher"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" \n handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"manyToManyAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacherNames"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" teacherIds"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 默认支持 "1, 2, 3" 格式')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" teacherNames"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充的格式默认为 src1, src2, src3")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,根据 "),a("code",[s._v("teacherIds")]),s._v(" 字段字符串中按分隔符分割的多个键值,查询关联的多个 "),a("code",[s._v("Teacher")]),s._v(" 对象,然后将 "),a("code",[s._v("Teacher")]),s._v(" 集合的 "),a("code",[s._v("name")]),s._v(" 属性映射为 "),a("code",[s._v("List")]),s._v(" 并赋值给 "),a("code",[s._v("StudentVO.teacherNames")]),s._v(" 字段。")]),s._v(" "),a("p",[s._v("这种字段映射遵循普通字段映射的语义,例如对象映射:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StudentVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacher"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" \n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teachers"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handlerName "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"manyToManyAssembleOperationHandler"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" teacherIds"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 默认支持 "1, 2, 3" 格式')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Teacher")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" teachers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在批量映射的情况下,返回的对象可以是数据源对象或数据源对象的属性集合。")]),s._v(" "),a("p",[a("strong",[s._v("更换分隔符")])]),s._v(" "),a("p",[s._v("默认情况下,若返回值为字符串,"),a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(" 总是尝试将其根据"),a("code",[s._v(",")]),s._v("分割为字符串集合,但如果有必要,用户也可以通过 "),a("code",[s._v("ManyToManyAssembleOperationHandler.setKeySplitter")]),s._v(" 方法设置自己需要的分隔符。")]),s._v(" "),a("p",[s._v("例如,如果希望使用"),a("code",[s._v("|")]),s._v("符号作为分隔符,则可以执行以下操作:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler")]),s._v(" handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 按 | 分割")]),s._v("\nhandler"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("setKeySplitter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("k "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("DefaultSplitter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"|"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{314:function(s,a,t){"use strict";t.r(a);var n=t(14),e=Object(n.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),a("p",[s._v("装配操作处理器 "),a("code",[s._v("AssembleOperateHandler")]),s._v(" 在整个装配过程中负责实际的属性读写操作,类似于 Jackson 中的序列化器("),a("code",[s._v("Serializer")]),s._v(")和反序列化器("),a("code",[s._v("Deserializer")]),s._v(")。与 Jackson 类似,如果我们需要处理特殊数据结构或具有特殊填充逻辑的 JavaBean,就需要更换不同的装配操作处理器。")]),s._v(" "),a("p",[s._v("有三种处理器的实现:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("OneToOneAssembleOperationHandler")]),s._v(":一对一装配操作处理器,也是默认的处理器;")]),s._v(" "),a("li",[a("code",[s._v("OneToManyAssembleOperationHandler")]),s._v(":一对多装配操作处理器;")]),s._v(" "),a("li",[a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(":多对多装配操作处理器;")])]),s._v(" "),a("p",[s._v("与其他组件一样,用户也可以实现 "),a("code",[s._v("AssembleOperationHandler")]),s._v(" 接口,并将其声明为 Spring 上下文中的一个组件,以实现自动注册,或者手动获取全局配置类进行注册。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-1-使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-1-使用"}},[s._v("#")]),s._v(" 3.2.1.使用")]),s._v(" "),a("p",[s._v("用户可以在 "),a("code",[s._v("@Assemble")]),s._v(" 注解的 "),a("code",[s._v("handler")]),s._v(" 属性或 "),a("code",[s._v("handlerType")]),s._v(" 属性中指定要使用的处理器。例如:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foo"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"oneToOneAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" alias"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("默认情况下,将会使用一对一装配处理器执行操作,即一个 "),a("code",[s._v("key")]),s._v(" 值只对应一个数据源对象。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-2-一对多装配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-2-一对多装配"}},[s._v("#")]),s._v(" 3.2.2.一对多装配")]),s._v(" "),a("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230320105459223.png",alt:"image-20230320105459223"}}),s._v(" "),a("p",[s._v("在一对多的情况下,一个属性对应多个数据源对象,即从数据源容器中查询数据时,一个键(key)可以查出一个集合或数组的情况。")]),s._v(" "),a("p",[s._v("例如,我们有一个名为 "),a("code",[s._v("customer")]),s._v(" 的容器,可以根据客户 id 查询客户,并返回按客户组别 id 分组的 "),a("code",[s._v("Map")]),s._v(" 集合:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 根据ID查询客户,返回的数据按客户组别ID分组")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Container")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" customerContainer "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("LambdaContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("forLambda")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ids "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" customerService"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("listByIds")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ids"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("stream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("groupBy")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("CustomerDO")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getGroupId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("现在,我们可以借助一对多装配处理器,批量提取数据源对象的属性,并将其赋值给目标对象的指定属性:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("CustomerVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"oneToManyAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"customerNames"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" customerNames"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,我们根据 id 集合获取按客户组别ID分组的客户集合,并提取 "),a("code",[s._v("CustomerDO.name")]),s._v(" 作为集合,然后赋值给 "),a("code",[s._v("CustomerVO.customerNames")]),s._v("。")]),s._v(" "),a("h2",{attrs:{id:"_3-2-3-多对多装配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-3-多对多装配"}},[s._v("#")]),s._v(" 3.2.3.多对多装配")]),s._v(" "),a("img",{staticStyle:{zoom:"33%"},attrs:{src:"https://img.xiajibagao.top/image-20230320105521429.png",alt:"image-20230320105521429"}}),s._v(" "),a("p",[s._v("在多对多的情况下,多个键(key)对应多个数据源对象,实际场景中,比较常见的情况有三种:")]),s._v(" "),a("ul",[a("li",[s._v("键字段是按特定分隔符拼接的字符串;")]),s._v(" "),a("li",[s._v("建字段是集合类型;")]),s._v(" "),a("li",[s._v("建字段是数组类型;")])]),s._v(" "),a("p",[s._v("例如,假设存在以下键字段类型:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" idStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 键字段为按分隔符拼接的字符串,例如:"a, b, c"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Set")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" idList"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 键字段为集合,例如:[a, b, c]")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" idArray"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 键字段为数组,例如:[a, b, c]")]),s._v("\n")])])]),a("p",[s._v("针对多个键字段映射,需要使用特定的装配操作处理器 "),a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(":")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StudentVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacher"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" \n handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"manyToManyAssembleOperationHandler"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacherNames"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" teacherIds"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 默认支持 "1, 2, 3" 格式')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" teacherNames"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充的格式默认为 src1, src2, src3")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,根据 "),a("code",[s._v("teacherIds")]),s._v(" 字段字符串中按分隔符分割的多个键值,查询关联的多个 "),a("code",[s._v("Teacher")]),s._v(" 对象,然后将 "),a("code",[s._v("Teacher")]),s._v(" 集合的 "),a("code",[s._v("name")]),s._v(" 属性映射为 "),a("code",[s._v("List")]),s._v(" 并赋值给 "),a("code",[s._v("StudentVO.teacherNames")]),s._v(" 字段。")]),s._v(" "),a("p",[s._v("这种字段映射遵循普通字段映射的语义,例如对象映射:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StudentVO")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n container "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teacher"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" \n props "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"teachers"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handlerName "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"manyToManyAssembleOperationHandler"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" teacherIds"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('// 默认支持 "1, 2, 3" 格式')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Teacher")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" teachers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在批量映射的情况下,返回的对象可以是数据源对象或数据源对象的属性集合。")]),s._v(" "),a("p",[a("strong",[s._v("更换分隔符")])]),s._v(" "),a("p",[s._v("默认情况下,若返回值为字符串,"),a("code",[s._v("ManyToManyAssembleOperationHandler")]),s._v(" 总是尝试将其根据"),a("code",[s._v(",")]),s._v("分割为字符串集合,但如果有必要,用户也可以通过 "),a("code",[s._v("ManyToManyAssembleOperationHandler.setKeySplitter")]),s._v(" 方法设置自己需要的分隔符。")]),s._v(" "),a("p",[s._v("例如,如果希望使用"),a("code",[s._v("|")]),s._v("符号作为分隔符,则可以执行以下操作:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler")]),s._v(" handler "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 按 | 分割")]),s._v("\nhandler"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("setKeySplitter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("k "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ManyToManyAssembleOperationHandler"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("DefaultSplitter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"|"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/42.1448611c.js b/docs/assets/js/42.0fef9c4c.js similarity index 99% rename from docs/assets/js/42.1448611c.js rename to docs/assets/js/42.0fef9c4c.js index a449b0be..94b8df4a 100644 --- a/docs/assets/js/42.1448611c.js +++ b/docs/assets/js/42.0fef9c4c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{317:function(s,a,t){"use strict";t.r(a);var e=t(14),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),a("p",[s._v("在某些情况下,我们需要填充的对象中可能嵌套了其他对象,这种情况下,我们需要先将这些嵌套对象拆分出来,然后再进行填充操作。这个将嵌套对象取出并展开的操作称为"),a("strong",[s._v("拆卸操作")]),s._v("。")]),s._v(" "),a("p",[s._v("嵌套对象可能存在多层级的情况,因此在执行填充操作之前,我们需要先完成拆卸操作,将所有的嵌套对象展开,然后再统一进行装配。")]),s._v(" "),a("p",[a("img",{attrs:{src:"https://img.xiajibagao.top/image-20230220182831112.png",alt:"拆卸操作示意图"}})]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),a("p",[s._v("拆卸操作只是为了展开嵌套对象,它是嵌套填充的第一步。")])]),s._v(" "),a("h2",{attrs:{id:"_3-4-1-在属性上声明"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-1-在属性上声明"}},[s._v("#")]),s._v(" 3.4.1.在属性上声明")]),s._v(" "),a("p",[s._v("我们可以直接在需要进行拆卸操作的属性上使用 "),a("code",[s._v("@Disassemble")]),s._v(" 注解进行声明:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,对于填充 "),a("code",[s._v("Department")]),s._v(" 对象之前,会先将 "),a("code",[s._v("Department")]),s._v(" 中的所有 "),a("code",[s._v("Employee")]),s._v(" 对象取出并展开。如果 "),a("code",[s._v("Employee")]),s._v(" 对象中还存在需要拆卸的嵌套对象,也会一并取出并展开,一直递归下去,直到所有的对象都被展开为止。")]),s._v(" "),a("p",[s._v("拆卸操作支持处理数组、集合 ("),a("code",[s._v("Collection")]),s._v(") 或单个对象。")]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),a("p",[s._v("和 "),a("code",[s._v("@Assemble")]),s._v(" 一样,可以在属性上重复声明 "),a("code",[s._v("@Disassemble")]),s._v(" 注解,但这样做没有实际意义。")])]),s._v(" "),a("h2",{attrs:{id:"_3-4-2-在类上声明"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-2-在类上声明"}},[s._v("#")]),s._v(" 3.4.2.在类上声明")]),s._v(" "),a("p",[s._v("与 "),a("code",[s._v("@Assemble")]),s._v(" 注解一样,我们也可以将 "),a("code",[s._v("@Disassemble")]),s._v(" 注解声明在类上:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 直接声明")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"employees"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("当在类级别上声明 "),a("code",[s._v("@Disassemble")]),s._v(" 注解时,需要使用 "),a("code",[s._v("key")]),s._v(" 属性指定需要拆卸的字段。")]),s._v(" "),a("h2",{attrs:{id:"_3-4-3-自动类型推断"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-3-自动类型推断"}},[s._v("#")]),s._v(" 3.4.3.自动类型推断")]),s._v(" "),a("p",[s._v("在某些情况下,无法在编译期确定要填充的对象类型。此时,可以不指定 "),a("code",[s._v("type")]),s._v(" 属性,而是在执行拆卸操作时动态推断类型:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 无法确定填充类型")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("上述示例中,无法在编译期确定 "),a("code",[s._v("employees")]),s._v(" 属性的类型,因此没有指定 "),a("code",[s._v("type")]),s._v(" 属性。在执行拆卸操作时,会动态推断 "),a("code",[s._v("employees")]),s._v(" 属性的类型。")]),s._v(" "),a("p",[s._v("这个功能是通过类型解析器 "),a("code",[s._v("TypeResolver")]),s._v(" 实现的。用户可以实现 "),a("code",[s._v("TypeResolver")]),s._v(" 接口来替换默认的类型解析器,以适应特定的需求。")]),s._v(" "),a("h2",{attrs:{id:"_3-4-4-拆卸操作处理器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-4-拆卸操作处理器"}},[s._v("#")]),s._v(" 3.4.4.拆卸操作处理器")]),s._v(" "),a("p",[s._v("与装配操作类似,拆卸操作也依赖于拆卸操作处理器 "),a("code",[s._v("DisassembleOperationHandler")]),s._v(" 来完成。用户可以在注解中使用 "),a("code",[s._v("handler")]),s._v(" 或 "),a("code",[s._v("handlerType")]),s._v(" 属性来指定要使用的处理器。")]),s._v(" "),a("p",[s._v("例如:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handlerType "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ReflectiveDisassembleOperationHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定操作处理器")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在配置解析过程中,会根据指定的类型和处理器类型获取对应的操作处理器。用户可以根据自己的需求,实现自定义的拆卸操作处理器,并通过 "),a("code",[s._v("handler")]),s._v(" 或 "),a("code",[s._v("handlerType")]),s._v(" 属性进行指定。")]),s._v(" "),a("p",[s._v("目前默认的,也是唯一的拆卸操作处理就是 "),a("code",[s._v("ReflectiveDisassembleOperationHandler")]),s._v(",因此一般可以不用指定。")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{313:function(s,a,t){"use strict";t.r(a);var e=t(14),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),a("p",[s._v("在某些情况下,我们需要填充的对象中可能嵌套了其他对象,这种情况下,我们需要先将这些嵌套对象拆分出来,然后再进行填充操作。这个将嵌套对象取出并展开的操作称为"),a("strong",[s._v("拆卸操作")]),s._v("。")]),s._v(" "),a("p",[s._v("嵌套对象可能存在多层级的情况,因此在执行填充操作之前,我们需要先完成拆卸操作,将所有的嵌套对象展开,然后再统一进行装配。")]),s._v(" "),a("p",[a("img",{attrs:{src:"https://img.xiajibagao.top/image-20230220182831112.png",alt:"拆卸操作示意图"}})]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),a("p",[s._v("拆卸操作只是为了展开嵌套对象,它是嵌套填充的第一步。")])]),s._v(" "),a("h2",{attrs:{id:"_3-4-1-在属性上声明"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-1-在属性上声明"}},[s._v("#")]),s._v(" 3.4.1.在属性上声明")]),s._v(" "),a("p",[s._v("我们可以直接在需要进行拆卸操作的属性上使用 "),a("code",[s._v("@Disassemble")]),s._v(" 注解进行声明:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在上面的示例中,对于填充 "),a("code",[s._v("Department")]),s._v(" 对象之前,会先将 "),a("code",[s._v("Department")]),s._v(" 中的所有 "),a("code",[s._v("Employee")]),s._v(" 对象取出并展开。如果 "),a("code",[s._v("Employee")]),s._v(" 对象中还存在需要拆卸的嵌套对象,也会一并取出并展开,一直递归下去,直到所有的对象都被展开为止。")]),s._v(" "),a("p",[s._v("拆卸操作支持处理数组、集合 ("),a("code",[s._v("Collection")]),s._v(") 或单个对象。")]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("TIP")]),s._v(" "),a("p",[s._v("和 "),a("code",[s._v("@Assemble")]),s._v(" 一样,可以在属性上重复声明 "),a("code",[s._v("@Disassemble")]),s._v(" 注解,但这样做没有实际意义。")])]),s._v(" "),a("h2",{attrs:{id:"_3-4-2-在类上声明"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-2-在类上声明"}},[s._v("#")]),s._v(" 3.4.2.在类上声明")]),s._v(" "),a("p",[s._v("与 "),a("code",[s._v("@Assemble")]),s._v(" 注解一样,我们也可以将 "),a("code",[s._v("@Disassemble")]),s._v(" 注解声明在类上:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 直接声明")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"employees"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("当在类级别上声明 "),a("code",[s._v("@Disassemble")]),s._v(" 注解时,需要使用 "),a("code",[s._v("key")]),s._v(" 属性指定需要拆卸的字段。")]),s._v(" "),a("h2",{attrs:{id:"_3-4-3-自动类型推断"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-3-自动类型推断"}},[s._v("#")]),s._v(" 3.4.3.自动类型推断")]),s._v(" "),a("p",[s._v("在某些情况下,无法在编译期确定要填充的对象类型。此时,可以不指定 "),a("code",[s._v("type")]),s._v(" 属性,而是在执行拆卸操作时动态推断类型:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 无法确定填充类型")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("上述示例中,无法在编译期确定 "),a("code",[s._v("employees")]),s._v(" 属性的类型,因此没有指定 "),a("code",[s._v("type")]),s._v(" 属性。在执行拆卸操作时,会动态推断 "),a("code",[s._v("employees")]),s._v(" 属性的类型。")]),s._v(" "),a("p",[s._v("这个功能是通过类型解析器 "),a("code",[s._v("TypeResolver")]),s._v(" 实现的。用户可以实现 "),a("code",[s._v("TypeResolver")]),s._v(" 接口来替换默认的类型解析器,以适应特定的需求。")]),s._v(" "),a("h2",{attrs:{id:"_3-4-4-拆卸操作处理器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-4-拆卸操作处理器"}},[s._v("#")]),s._v(" 3.4.4.拆卸操作处理器")]),s._v(" "),a("p",[s._v("与装配操作类似,拆卸操作也依赖于拆卸操作处理器 "),a("code",[s._v("DisassembleOperationHandler")]),s._v(" 来完成。用户可以在注解中使用 "),a("code",[s._v("handler")]),s._v(" 或 "),a("code",[s._v("handlerType")]),s._v(" 属性来指定要使用的处理器。")]),s._v(" "),a("p",[s._v("例如:")]),s._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Department")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n handlerType "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ReflectiveDisassembleOperationHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 指定操作处理器")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Employee")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" employees"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("在配置解析过程中,会根据指定的类型和处理器类型获取对应的操作处理器。用户可以根据自己的需求,实现自定义的拆卸操作处理器,并通过 "),a("code",[s._v("handler")]),s._v(" 或 "),a("code",[s._v("handlerType")]),s._v(" 属性进行指定。")]),s._v(" "),a("p",[s._v("目前默认的,也是唯一的拆卸操作处理就是 "),a("code",[s._v("ReflectiveDisassembleOperationHandler")]),s._v(",因此一般可以不用指定。")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/43.5f5b2cc2.js b/docs/assets/js/43.390dac8c.js similarity index 99% rename from docs/assets/js/43.5f5b2cc2.js rename to docs/assets/js/43.390dac8c.js index 81b70ff6..7f3f1abb 100644 --- a/docs/assets/js/43.5f5b2cc2.js +++ b/docs/assets/js/43.390dac8c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{316:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),t("p",[t("code",[s._v("crane4j")]),s._v(" 提供了分组填充的功能,类似于 "),t("code",[s._v("hibernate-validator")]),s._v(" 中的分组校验。")]),s._v(" "),t("p",[s._v("分组填充功能允许您定义不同的填充组,然后在使用 "),t("code",[s._v("@Assemble")]),s._v(" 或 "),t("code",[s._v("@Disassemble")]),s._v(" 进行填充操作时,通过 "),t("code",[s._v("groups")]),s._v(" 属性指定要使用的填充组。这样,只有与指定组匹配的属性才会被填充或拆卸,例如在创建对象时只填充必要的属性,而在更新对象时填充所有属性。")]),s._v(" "),t("img",{staticStyle:{zoom:"150%"},attrs:{src:"https://img.xiajibagao.top/image-20230225012401927.png",alt:"image-20230225012401927"}}),s._v(" "),t("h2",{attrs:{id:"_3-5-1-为操作分组"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-1-为操作分组"}},[s._v("#")]),s._v(" 3.5.1.为操作分组")]),s._v(" "),t("p",[s._v("在 "),t("code",[s._v("crane4j")]),s._v(" 中,您可以通过在 "),t("code",[s._v("@Assemble")]),s._v(" 和 "),t("code",[s._v("@Disassemble")]),s._v(" 注解中使用 "),t("code",[s._v("groups")]),s._v(" 属性来指定分组。")]),s._v(" "),t("p",[s._v("比如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserVO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"role"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"role"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" role"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在示例中,我们有一个 "),t("code",[s._v("UserVO")]),s._v(" 类,其中有一个 "),t("code",[s._v("id")]),s._v(" 属性,我们声明了两个装配操作:")]),s._v(" "),t("ul",[t("li",[s._v("第一个装配操作是根据 "),t("code",[s._v("id")]),s._v(" 装配 "),t("code",[s._v("name")]),s._v(" 属性,这个装配操作只在 "),t("code",[s._v("admin")]),s._v(" 组中生效;")]),s._v(" "),t("li",[s._v("第二个装配操作是根据 "),t("code",[s._v("id")]),s._v(" 装配 "),t("code",[s._v("role")]),s._v(" 属性,这个装配操作在 "),t("code",[s._v("base")]),s._v(" 和 "),t("code",[s._v("admin")]),s._v(" 组中生效;")])]),s._v(" "),t("p",[s._v("当我们执行填充操作时,如果指定的组中包含了装配操作的分组,那么该装配操作将生效,否则,它将被忽略。")]),s._v(" "),t("p",[s._v("类似的,"),t("code",[s._v("@Disassemble")]),s._v(" 注解也支持使用 "),t("code",[s._v("groups")]),s._v(" 属性。")]),s._v(" "),t("p",[s._v("比如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"nested"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" fooList"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,仅当指定执行操作组为 "),t("code",[s._v("nested")]),s._v(" 时,才会执行对 "),t("code",[s._v("fooList")]),s._v(" 的拆卸操作。")]),s._v(" "),t("h2",{attrs:{id:"_3-5-2-按分组规则执行操作"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-2-按分组规则执行操作"}},[s._v("#")]),s._v(" 3.5.2.按分组规则执行操作")]),s._v(" "),t("p",[s._v("在 "),t("code",[s._v("crane4j")]),s._v(" 中,您可以在手动填充和自动填充的情况下使用分组功能。")]),s._v(" "),t("p",[s._v("对于手动填充,您可以使用 "),t("code",[s._v("OperateTemplate")]),s._v(" 的不同重载方法来设置本次填充操作的执行组:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的任何一个组匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfMatchAnyGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的任何一个组都不匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfNoneMatchAnyGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的所有组都匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfMatchAllGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 仅执行通过指定过滤器条件的操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("execute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Predicate")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("super")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyTriggerOperation")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" filter"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("当自动填充时,您可以在 "),t("code",[s._v("@AutoOperate")]),s._v(" 注解中使用 "),t("code",[s._v("includes")]),s._v(" 属性来指定要执行填充操作的组:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充返回值")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@AutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" includes "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getFooList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// do nothing")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充参数")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ArgAutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@AutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("value "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foos"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" includes "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setFooList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// do nothing")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{317:function(s,t,a){"use strict";a.r(t);var n=a(14),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[s._v("#")]),s._v(" 概述")]),s._v(" "),t("p",[t("code",[s._v("crane4j")]),s._v(" 提供了分组填充的功能,类似于 "),t("code",[s._v("hibernate-validator")]),s._v(" 中的分组校验。")]),s._v(" "),t("p",[s._v("分组填充功能允许您定义不同的填充组,然后在使用 "),t("code",[s._v("@Assemble")]),s._v(" 或 "),t("code",[s._v("@Disassemble")]),s._v(" 进行填充操作时,通过 "),t("code",[s._v("groups")]),s._v(" 属性指定要使用的填充组。这样,只有与指定组匹配的属性才会被填充或拆卸,例如在创建对象时只填充必要的属性,而在更新对象时填充所有属性。")]),s._v(" "),t("img",{staticStyle:{zoom:"150%"},attrs:{src:"https://img.xiajibagao.top/image-20230225012401927.png",alt:"image-20230225012401927"}}),s._v(" "),t("h2",{attrs:{id:"_3-5-1-为操作分组"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-1-为操作分组"}},[s._v("#")]),s._v(" 3.5.1.为操作分组")]),s._v(" "),t("p",[s._v("在 "),t("code",[s._v("crane4j")]),s._v(" 中,您可以通过在 "),t("code",[s._v("@Assemble")]),s._v(" 和 "),t("code",[s._v("@Disassemble")]),s._v(" 注解中使用 "),t("code",[s._v("groups")]),s._v(" 属性来指定分组。")]),s._v(" "),t("p",[s._v("比如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserVO")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"role"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"role"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" role"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在示例中,我们有一个 "),t("code",[s._v("UserVO")]),s._v(" 类,其中有一个 "),t("code",[s._v("id")]),s._v(" 属性,我们声明了两个装配操作:")]),s._v(" "),t("ul",[t("li",[s._v("第一个装配操作是根据 "),t("code",[s._v("id")]),s._v(" 装配 "),t("code",[s._v("name")]),s._v(" 属性,这个装配操作只在 "),t("code",[s._v("admin")]),s._v(" 组中生效;")]),s._v(" "),t("li",[s._v("第二个装配操作是根据 "),t("code",[s._v("id")]),s._v(" 装配 "),t("code",[s._v("role")]),s._v(" 属性,这个装配操作在 "),t("code",[s._v("base")]),s._v(" 和 "),t("code",[s._v("admin")]),s._v(" 组中生效;")])]),s._v(" "),t("p",[s._v("当我们执行填充操作时,如果指定的组中包含了装配操作的分组,那么该装配操作将生效,否则,它将被忽略。")]),s._v(" "),t("p",[s._v("类似的,"),t("code",[s._v("@Disassemble")]),s._v(" 注解也支持使用 "),t("code",[s._v("groups")]),s._v(" 属性。")]),s._v(" "),t("p",[s._v("比如:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Assemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("container "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" props "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Mapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("src "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"admin"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Integer")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Disassemble")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" groups "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"nested"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" fooList"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("在上述示例中,仅当指定执行操作组为 "),t("code",[s._v("nested")]),s._v(" 时,才会执行对 "),t("code",[s._v("fooList")]),s._v(" 的拆卸操作。")]),s._v(" "),t("h2",{attrs:{id:"_3-5-2-按分组规则执行操作"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-2-按分组规则执行操作"}},[s._v("#")]),s._v(" 3.5.2.按分组规则执行操作")]),s._v(" "),t("p",[s._v("在 "),t("code",[s._v("crane4j")]),s._v(" 中,您可以在手动填充和自动填充的情况下使用分组功能。")]),s._v(" "),t("p",[s._v("对于手动填充,您可以使用 "),t("code",[s._v("OperateTemplate")]),s._v(" 的不同重载方法来设置本次填充操作的执行组:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的任何一个组匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfMatchAnyGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的任何一个组都不匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfNoneMatchAnyGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 如果目标对象所属的填充组与指定的所有组都匹配,执行填充操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeIfMatchAllGroups")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v(" groups"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 仅执行通过指定过滤器条件的操作")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("execute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" target"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Predicate")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("super")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyTriggerOperation")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" filter"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("当自动填充时,您可以在 "),t("code",[s._v("@AutoOperate")]),s._v(" 注解中使用 "),t("code",[s._v("includes")]),s._v(" 属性来指定要执行填充操作的组:")]),s._v(" "),t("div",{staticClass:"language-java extra-class"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充返回值")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@AutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" includes "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getFooList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// do nothing")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 填充参数")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ArgAutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@AutoOperate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("value "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"foos"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" type "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" includes "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"base"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setFooList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Foo")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" foos"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// do nothing")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/44.ae924029.js b/docs/assets/js/44.7ceb7760.js similarity index 99% rename from docs/assets/js/44.ae924029.js rename to docs/assets/js/44.7ceb7760.js index 7728435f..738d2e88 100644 --- a/docs/assets/js/44.ae924029.js +++ b/docs/assets/js/44.7ceb7760.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{321:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,默认情况下,操作的排序按照以下规则进行:")]),t._v(" "),s("ul",[s("li",[t._v("直接在属性上使用 "),s("code",[t._v("@Assemble")]),t._v(" 声明的操作按属性的顺序进行排序;")]),t._v(" "),s("li",[t._v("通过 "),s("code",[t._v("@Operations")]),t._v(" 声明的操作按照它们的声明顺序进行排序;")]),t._v(" "),s("li",[t._v("在同一类中,属性上声明的操作优先于类上声明的操作;")]),t._v(" "),s("li",[t._v("在不同类中,子类中声明的操作优先于父类中声明的操作;")])]),t._v(" "),s("p",[t._v("除了默认排序规则,您还可以使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("sort")]),t._v(" 属性或 Spring 的 "),s("code",[t._v("@Order")]),t._v(" 注解来指定不同操作之间的顺序。")]),t._v(" "),s("h2",{attrs:{id:"_3-6-1-指定排序值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-1-指定排序值"}},[t._v("#")]),t._v(" 3.6.1.指定排序值")]),t._v(" "),s("p",[t._v("通过 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("sort")]),t._v(" 属性,或者 Spring 的 "),s("code",[t._v("@Order")]),t._v(" 注解可以指定操作值,其中:")]),t._v(" "),s("ul",[s("li",[t._v("值越小,操作的排序越靠前;")]),t._v(" "),s("li",[s("code",[t._v("@Assemble")]),t._v("注解的"),s("code",[t._v("sort")]),t._v("属性优先于Spring的"),s("code",[t._v("@Order")]),t._v("注解;")]),t._v(" "),s("li",[t._v("当属性上存在多个操作声明时,"),s("code",[t._v("@Order")]),t._v("注解适用于所有声明的操作;")])]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 默认排序值为 Integer.MAX_VALUE")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,根据排序值, "),s("code",[t._v("Student")]),t._v(" 类中的三个操作的顺序为 "),s("code",[t._v("id1 -> id3 -> id2")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_3-6-2-按顺序执行"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-2-按顺序执行"}},[t._v("#")]),t._v(" 3.6.2.按顺序执行")]),t._v(" "),s("p",[t._v("需要注意的是,"),s("strong",[t._v("排序值并不一定代表最终的执行顺序")]),t._v(",它只代表在遍历 "),s("code",[t._v("BeanOperations")]),t._v(" 中的装配操作时的顺序。最终的执行顺序需要通过 "),s("code",[t._v("BeanOperationExecutor")]),t._v(" 来保证。")]),t._v(" "),s("p",[t._v("如果您希望操作按照严格的排序执行,比如想要实现"),s("strong",[t._v("级联装配")]),t._v("的效果,可以指定执行器为有序执行器 "),s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(" 。")]),t._v(" "),s("p",[t._v("比如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("需要注意的是,有序执行器相对于其他执行器可能会在数据源获取方面产生"),s("strong",[t._v("额外的性能消耗")]),t._v("。")]),t._v(" "),s("p",[t._v("在上述示例中,使用有序执行器将会对 "),s("code",[t._v("student")]),t._v(" 进行三次访问,而使用无序执行器则只需要一次请求。因此,在选择执行器时,您需要权衡性能和执行顺序的需求,选择最适合您的场景的执行器。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("拆卸操作和装配操作都可以进行排序。然而,为了使装配操作可以一次性尽可能多地提交待处理对象给执行器,一般情况下执行器会先执行所有的拆卸操作,然后再执行装配操作。这样可以提高执行效率和性能;")]),t._v(" "),s("li",[t._v("关于执行器,请参阅"),s("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[t._v("操作执行器")]),t._v("一节;")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{323:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"概述"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("crane4j")]),t._v(" 中,默认情况下,操作的排序按照以下规则进行:")]),t._v(" "),s("ul",[s("li",[t._v("直接在属性上使用 "),s("code",[t._v("@Assemble")]),t._v(" 声明的操作按属性的顺序进行排序;")]),t._v(" "),s("li",[t._v("通过 "),s("code",[t._v("@Operations")]),t._v(" 声明的操作按照它们的声明顺序进行排序;")]),t._v(" "),s("li",[t._v("在同一类中,属性上声明的操作优先于类上声明的操作;")]),t._v(" "),s("li",[t._v("在不同类中,子类中声明的操作优先于父类中声明的操作;")])]),t._v(" "),s("p",[t._v("除了默认排序规则,您还可以使用 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("sort")]),t._v(" 属性或 Spring 的 "),s("code",[t._v("@Order")]),t._v(" 注解来指定不同操作之间的顺序。")]),t._v(" "),s("h2",{attrs:{id:"_3-6-1-指定排序值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-1-指定排序值"}},[t._v("#")]),t._v(" 3.6.1.指定排序值")]),t._v(" "),s("p",[t._v("通过 "),s("code",[t._v("@Assemble")]),t._v(" 注解的 "),s("code",[t._v("sort")]),t._v(" 属性,或者 Spring 的 "),s("code",[t._v("@Order")]),t._v(" 注解可以指定操作值,其中:")]),t._v(" "),s("ul",[s("li",[t._v("值越小,操作的排序越靠前;")]),t._v(" "),s("li",[s("code",[t._v("@Assemble")]),t._v("注解的"),s("code",[t._v("sort")]),t._v("属性优先于Spring的"),s("code",[t._v("@Order")]),t._v("注解;")]),t._v(" "),s("li",[t._v("当属性上存在多个操作声明时,"),s("code",[t._v("@Order")]),t._v("注解适用于所有声明的操作;")])]),t._v(" "),s("p",[t._v("例如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 默认排序值为 Integer.MAX_VALUE")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在上述示例中,根据排序值, "),s("code",[t._v("Student")]),t._v(" 类中的三个操作的顺序为 "),s("code",[t._v("id1 -> id3 -> id2")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_3-6-2-按顺序执行"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-2-按顺序执行"}},[t._v("#")]),t._v(" 3.6.2.按顺序执行")]),t._v(" "),s("p",[t._v("需要注意的是,"),s("strong",[t._v("排序值并不一定代表最终的执行顺序")]),t._v(",它只代表在遍历 "),s("code",[t._v("BeanOperations")]),t._v(" 中的装配操作时的顺序。最终的执行顺序需要通过 "),s("code",[t._v("BeanOperationExecutor")]),t._v(" 来保证。")]),t._v(" "),s("p",[t._v("如果您希望操作按照严格的排序执行,比如想要实现"),s("strong",[t._v("级联装配")]),t._v("的效果,可以指定执行器为有序执行器 "),s("code",[t._v("OrderedBeanOperationExecutor")]),t._v(" 。")]),t._v(" "),s("p",[t._v("比如:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"student"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),t._v(" id4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("需要注意的是,有序执行器相对于其他执行器可能会在数据源获取方面产生"),s("strong",[t._v("额外的性能消耗")]),t._v("。")]),t._v(" "),s("p",[t._v("在上述示例中,使用有序执行器将会对 "),s("code",[t._v("student")]),t._v(" 进行三次访问,而使用无序执行器则只需要一次请求。因此,在选择执行器时,您需要权衡性能和执行顺序的需求,选择最适合您的场景的执行器。")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("ul",[s("li",[t._v("拆卸操作和装配操作都可以进行排序。然而,为了使装配操作可以一次性尽可能多地提交待处理对象给执行器,一般情况下执行器会先执行所有的拆卸操作,然后再执行装配操作。这样可以提高执行效率和性能;")]),t._v(" "),s("li",[t._v("关于执行器,请参阅"),s("RouterLink",{attrs:{to:"/execute/4.3.操作执行器.html"}},[t._v("操作执行器")]),t._v("一节;")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/45.200f9dcf.js b/docs/assets/js/45.57524ff9.js similarity index 99% rename from docs/assets/js/45.200f9dcf.js rename to docs/assets/js/45.57524ff9.js index 2c66a537..c6dd12a9 100644 --- a/docs/assets/js/45.200f9dcf.js +++ b/docs/assets/js/45.57524ff9.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{318:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),a("p",[t._v("操作者接口的设计灵感源自于 "),a("code",[t._v("MapStruct")]),t._v(" 的 "),a("code",[t._v("Mapper")]),t._v(" 接口。它提供了一种手动填充的补充方式,用于处理某些无法直接在类上配置注解的业务场景。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("ul",[a("li",[t._v("用于填充的对象是 "),a("code",[t._v("JSONObject")]),t._v(" / "),a("code",[t._v("Map")]),t._v(",就没有对应的 Java 类,因此也无法在类上或类的属性上添加注解配置;")]),t._v(" "),a("li",[t._v("填充的对象的字段非常像,但是它们确实不是一个类,也不存在提取公共父类的可能,又不想要每个类都重复配置;")])]),t._v(" "),a("p",[t._v("除了手动构建一个 "),a("code",[t._v("BeanOperations")]),t._v(" 对象并调用执行器这种复杂的方法之外,还可以通过使用操作者接口来完成这类操作。")]),t._v(" "),a("p",[t._v("我们可以通过简单的注解配置将一个接口变为操作者,然后在其有参的抽象方法上通过 "),a("code",[t._v("@Assemble")]),t._v(" 注解配置装配操作,此后,我们可以将任何对象或对象集合作为参数传入该方法,在调用后,将会按抽象方法上的操作配置去填充传入的对象或对象集合。")]),t._v(" "),a("h2",{attrs:{id:"_3-7-1-基本使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-1-基本使用"}},[t._v("#")]),t._v(" 3.7.1.基本使用")]),t._v(" "),a("p",[t._v("首先,在一个"),a("strong",[t._v("接口")]),t._v("上添加 "),a("code",[t._v("@Operator")]),t._v(" 注解,将其声明为操作者。然后,在抽象方法上使用 "),a("code",[t._v("@Assemble")]),t._v(" 注解配置装配操作,就像在类或类属性上进行配置一样。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 所有传入的 map 对象,都会根据 id 对应的值进行填充")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("接下来,我们使用代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 生成操作者接口的代理类,并获得具备填充能力的代理对象:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在 spring 环境可以跳过这一步,直接从 spring 容器获取相关组件")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建操作者接口的代理工厂")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotationFinder")]),t._v(" annotationFinder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),t._v(" operatorProxyFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" annotationFinder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 向代理工厂添加抽象方法适配器")]),t._v("\noperatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getConverterManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 通过代理工厂创建代理对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" operatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("在调用 "),a("code",[t._v("operate")]),t._v(" 方法后,我们的输入参数 "),a("code",[t._v("targets")]),t._v(" 将根据 "),a("code",[t._v("operate")]),t._v(" 方法上的配置进行填充:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用抽象方法完成填充操作")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IntStream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("rangeClosed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mapToObj")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" target "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toList")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),a("ul",[a("li",[t._v("所有 "),a("code",[t._v("AssembleXXX")]),t._v(" 格式的操作配置注解都可以在方法上使用,因此操作者接口的配置方式与基于类或属性的方式基本相同;")]),t._v(" "),a("li",[t._v("配置解析器 "),a("code",[t._v("BeanOperationParser")]),t._v(" 可以从任何带注解的 "),a("code",[t._v("AnnotatedElement")]),t._v(" 解析并获取 "),a("code",[t._v("BeanOperations")]),t._v(" 配置对象,不仅限于 "),a("code",[t._v("Class")]),t._v(" 或 "),a("code",[t._v("Method")]),t._v("。操作者接口受益于此特性,你可以通过它来扩展更多玩法;")])])]),t._v(" "),a("h2",{attrs:{id:"_3-7-2-在-spring-中使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-2-在-spring-中使用"}},[t._v("#")]),t._v(" 3.7.2.在 Spring 中使用")]),t._v(" "),a("p",[t._v("类似于 MyBatis,你可以在 Spring 环境中的启动类或配置类上添加 "),a("code",[t._v("@OperatorScan")]),t._v(" 注解,方便地批量扫描、添加或排除操作者接口:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@OperatorScan")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n scan "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cn.crane4j.example.operators"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cn.crane4j.spring.example.operators"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n includes "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" excludes "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExcludeOpeator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Configuration")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("protected")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Application")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("在项目启动后,将自动为接口创建 "),a("code",[t._v("BeanDefinition")]),t._v(",并在 Spring 容器中创建对应的 Bean。因此,你可以像使用 MyBatis 的 Mapper 一样,通过依赖注入来使用操作者接口:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooService")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Autowired")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooOperator")]),t._v(" operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注入操作者接口")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-3-动态数据源容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-动态数据源容器"}},[t._v("#")]),t._v(" 3.7.3.动态数据源容器")]),t._v(" "),a("p",[t._v("通过向操作者接口的代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 注册 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 方法适配器,我们可以令具有不止一个参数的抽象方法支持动态数据源功能:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在 spring 环境可以跳过这一步,直接从 spring 容器获取相关组件")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 上文创建的全局配置对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),t._v(" operatorProxyFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 上文创建的代理工厂")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyMethodFactory")]),t._v(" proxyMethodFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getConverterManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleParameterNameFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("proxyMethodFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"_3-7-3-1-声明参数为容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-1-声明参数为容器"}},[t._v("#")]),t._v(" 3.7.3.1.声明参数为容器")]),t._v(" "),a("p",[t._v("操作者接口在一次执行中可以使用临时容器来替换原有的数据源容器。在方法的参数中,除了第一个参数外,其他参数将被传入作为临时容器。")]),t._v(" "),a("p",[t._v("例如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface3")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerParam")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" tempData"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("在上面的示例中,我们将方法的第二个参数指定为临时数据源容器。这意味着,在执行操作时,会直接使用传入的 "),a("code",[t._v("Map")]),t._v(' 对象作为名为 "test" 的数据源容器,而不是使用全局配置类中的容器。')]),t._v(" "),a("p",[t._v("当然,我们也可以不使用 "),a("code",[t._v("@ContainerParam")]),t._v(" 注解,默认情况下,参数名将作为临时容器的命名空间。比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 写法等同于")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// void operate(Collection> targets, @ContainerParam("test") Map tempData);')]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" test"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("div",{staticClass:"custom-block warning"},[a("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),a("p",[t._v("在非 spring 环境中,需要用户自己开启编译保留参数名的选项,不然编译后参数名会变为 "),a("code",[t._v("arg0")]),t._v("、"),a("code",[t._v("arg1")]),t._v(" 这种格式。")])]),t._v(" "),a("h3",{attrs:{id:"_3-7-3-2-使用参数容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-2-使用参数容器"}},[t._v("#")]),t._v(" 3.7.3.2.使用参数容器")]),t._v(" "),a("p",[t._v("我们可以按照以下方式使用它:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" operatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个待处理对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" target "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntarget"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collections")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("singletonList")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// source 将作为临时数据源")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" source "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsource"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name1"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充待处理对象,数据源容器 test 将会直接返回 source 作为本次填充的数据源对象 ")]),t._v("\noperator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" source"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Assert")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("assertEquals")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name1"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"_3-7-3-3-参数适配器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-3-参数适配器"}},[t._v("#")]),t._v(" 3.7.3.3.参数适配器")]),t._v(" "),a("p",[t._v("这个功能是基于 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 实现的,默认支持以下三种类型的参数适配:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("Map")]),t._v(":参数将被适配为 "),a("code",[t._v("ConstantContainer")]),t._v(";")]),t._v(" "),a("li",[a("code",[t._v("Container")]),t._v(":直接使用;")]),t._v(" "),a("li",[a("code",[t._v("DataProvider")]),t._v(":参数将被适配为 "),a("code",[t._v("LambdaContainer")]),t._v(";")])]),t._v(" "),a("p",[t._v("如果有必要,用户还可以通过 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 的 "),a("code",[t._v("addAdaptorProvider")]),t._v(" 方法添加其他类型的参数适配器:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" factory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将 LinkedHashMap 类型的参数适配为 ConstantContainer")]),t._v("\nfactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addAdaptorProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LinkedHashMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" parameter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("\n\targ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" arg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-4-指定执行器和解析器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-4-指定执行器和解析器"}},[t._v("#")]),t._v(" 3.7.4.指定执行器和解析器")]),t._v(" "),a("p",[t._v("类似于 "),a("code",[t._v("@AutoOperate")]),t._v(","),a("code",[t._v("@Operator")]),t._v(" 接口也可以指定用于执行操作的执行器和配置解析器。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n executorType "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderedBeanOperationExecutor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n parserType "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TypeHierarchyBeanOperationParser")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-5-代理方法工厂"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-5-代理方法工厂"}},[t._v("#")]),t._v(" 3.7.5.代理方法工厂")]),t._v(" "),a("p",[t._v("与 Spring 中将被 "),a("code",[t._v("@EventListener")]),t._v(" 注解的方法适配为监听器的模式类似,操作者接口中抽象方法的解析也是基于策略模式。")]),t._v(" "),a("p",[t._v("操作者的代理方法工厂 "),a("code",[t._v("OperatorProxyMethodFactory")]),t._v(" 默认提供了两种实现:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("DefaultProxyMethodFactory")]),t._v(":默认的代理方法工厂,支持处理所有有参方法;")]),t._v(" "),a("li",[a("code",[t._v("DynamicSourceProxyMethodFactory")]),t._v(":动态数据源方法工厂,用于支持有不止一个参数的方法;")])]),t._v(" "),a("p",[t._v("接口中的一个抽象方法仅会使用最匹配的工厂去生成代理方法。因此若有必要,用户也可以自行实现接口并提高工厂的优先级以替换默认策略。")]),t._v(" "),a("p",[t._v("在 Spring 环境中,只需将自定义工厂类声明为 Spring Bean,即可自动注册。在非 Spring 环境中,用户需要在创建代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 时将所需的方法工厂作为参数传入。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{319:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"概述"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),a("p",[t._v("操作者接口的设计灵感源自于 "),a("code",[t._v("MapStruct")]),t._v(" 的 "),a("code",[t._v("Mapper")]),t._v(" 接口。它提供了一种手动填充的补充方式,用于处理某些无法直接在类上配置注解的业务场景。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("ul",[a("li",[t._v("用于填充的对象是 "),a("code",[t._v("JSONObject")]),t._v(" / "),a("code",[t._v("Map")]),t._v(",就没有对应的 Java 类,因此也无法在类上或类的属性上添加注解配置;")]),t._v(" "),a("li",[t._v("填充的对象的字段非常像,但是它们确实不是一个类,也不存在提取公共父类的可能,又不想要每个类都重复配置;")])]),t._v(" "),a("p",[t._v("除了手动构建一个 "),a("code",[t._v("BeanOperations")]),t._v(" 对象并调用执行器这种复杂的方法之外,还可以通过使用操作者接口来完成这类操作。")]),t._v(" "),a("p",[t._v("我们可以通过简单的注解配置将一个接口变为操作者,然后在其有参的抽象方法上通过 "),a("code",[t._v("@Assemble")]),t._v(" 注解配置装配操作,此后,我们可以将任何对象或对象集合作为参数传入该方法,在调用后,将会按抽象方法上的操作配置去填充传入的对象或对象集合。")]),t._v(" "),a("h2",{attrs:{id:"_3-7-1-基本使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-1-基本使用"}},[t._v("#")]),t._v(" 3.7.1.基本使用")]),t._v(" "),a("p",[t._v("首先,在一个"),a("strong",[t._v("接口")]),t._v("上添加 "),a("code",[t._v("@Operator")]),t._v(" 注解,将其声明为操作者。然后,在抽象方法上使用 "),a("code",[t._v("@Assemble")]),t._v(" 注解配置装配操作,就像在类或类属性上进行配置一样。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 所有传入的 map 对象,都会根据 id 对应的值进行填充")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("接下来,我们使用代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 生成操作者接口的代理类,并获得具备填充能力的代理对象:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在 spring 环境可以跳过这一步,直接从 spring 容器获取相关组件")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建操作者接口的代理工厂")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCrane4jGlobalConfiguration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnnotationFinder")]),t._v(" annotationFinder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),t._v(" operatorProxyFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" annotationFinder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 向代理工厂添加抽象方法适配器")]),t._v("\noperatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getConverterManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 通过代理工厂创建代理对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" operatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("在调用 "),a("code",[t._v("operate")]),t._v(" 方法后,我们的输入参数 "),a("code",[t._v("targets")]),t._v(" 将根据 "),a("code",[t._v("operate")]),t._v(" 方法上的配置进行填充:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用抽象方法完成填充操作")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IntStream")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("rangeClosed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mapToObj")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" target "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collectors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toList")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),a("ul",[a("li",[t._v("所有 "),a("code",[t._v("AssembleXXX")]),t._v(" 格式的操作配置注解都可以在方法上使用,因此操作者接口的配置方式与基于类或属性的方式基本相同;")]),t._v(" "),a("li",[t._v("配置解析器 "),a("code",[t._v("BeanOperationParser")]),t._v(" 可以从任何带注解的 "),a("code",[t._v("AnnotatedElement")]),t._v(" 解析并获取 "),a("code",[t._v("BeanOperations")]),t._v(" 配置对象,不仅限于 "),a("code",[t._v("Class")]),t._v(" 或 "),a("code",[t._v("Method")]),t._v("。操作者接口受益于此特性,你可以通过它来扩展更多玩法;")])])]),t._v(" "),a("h2",{attrs:{id:"_3-7-2-在-spring-中使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-2-在-spring-中使用"}},[t._v("#")]),t._v(" 3.7.2.在 Spring 中使用")]),t._v(" "),a("p",[t._v("类似于 MyBatis,你可以在 Spring 环境中的启动类或配置类上添加 "),a("code",[t._v("@OperatorScan")]),t._v(" 注解,方便地批量扫描、添加或排除操作者接口:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@OperatorScan")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n scan "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cn.crane4j.example.operators"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cn.crane4j.spring.example.operators"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n includes "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooOperator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" excludes "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExcludeOpeator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Configuration")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("protected")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Application")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("在项目启动后,将自动为接口创建 "),a("code",[t._v("BeanDefinition")]),t._v(",并在 Spring 容器中创建对应的 Bean。因此,你可以像使用 MyBatis 的 Mapper 一样,通过依赖注入来使用操作者接口:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooService")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Autowired")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FooOperator")]),t._v(" operator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 注入操作者接口")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-3-动态数据源容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-动态数据源容器"}},[t._v("#")]),t._v(" 3.7.3.动态数据源容器")]),t._v(" "),a("p",[t._v("通过向操作者接口的代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 注册 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 方法适配器,我们可以令具有不止一个参数的抽象方法支持动态数据源功能:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在 spring 环境可以跳过这一步,直接从 spring 容器获取相关组件")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Crane4jGlobalConfiguration")]),t._v(" configuration "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 上文创建的全局配置对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyFactory")]),t._v(" operatorProxyFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 上文创建的代理工厂")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorProxyMethodFactory")]),t._v(" proxyMethodFactory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n configuration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getConverterManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleParameterNameFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleAnnotationFinder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noperatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("proxyMethodFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"_3-7-3-1-声明参数为容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-1-声明参数为容器"}},[t._v("#")]),t._v(" 3.7.3.1.声明参数为容器")]),t._v(" "),a("p",[t._v("操作者接口在一次执行中可以使用临时容器来替换原有的数据源容器。在方法的参数中,除了第一个参数外,其他参数将被传入作为临时容器。")]),t._v(" "),a("p",[t._v("例如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface3")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ContainerParam")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" tempData"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("在上面的示例中,我们将方法的第二个参数指定为临时数据源容器。这意味着,在执行操作时,会直接使用传入的 "),a("code",[t._v("Map")]),t._v(' 对象作为名为 "test" 的数据源容器,而不是使用全局配置类中的容器。')]),t._v(" "),a("p",[t._v("当然,我们也可以不使用 "),a("code",[t._v("@ContainerParam")]),t._v(" 注解,默认情况下,参数名将作为临时容器的命名空间。比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 写法等同于")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// void operate(Collection> targets, @ContainerParam("test") Map tempData);')]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" test"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("div",{staticClass:"custom-block warning"},[a("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),a("p",[t._v("在非 spring 环境中,需要用户自己开启编译保留参数名的选项,不然编译后参数名会变为 "),a("code",[t._v("arg0")]),t._v("、"),a("code",[t._v("arg1")]),t._v(" 这种格式。")])]),t._v(" "),a("h3",{attrs:{id:"_3-7-3-2-使用参数容器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-2-使用参数容器"}},[t._v("#")]),t._v(" 3.7.3.2.使用参数容器")]),t._v(" "),a("p",[t._v("我们可以按照以下方式使用它:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" operator "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" operatorProxyFactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 声明一个待处理对象")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" target "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntarget"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collections")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("singletonList")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// source 将作为临时数据源")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Integer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" source "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HashMap")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nsource"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name1"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 填充待处理对象,数据源容器 test 将会直接返回 source 作为本次填充的数据源对象 ")]),t._v("\noperator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" source"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Assert")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("assertEquals")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name1"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" target"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"_3-7-3-3-参数适配器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-3-3-参数适配器"}},[t._v("#")]),t._v(" 3.7.3.3.参数适配器")]),t._v(" "),a("p",[t._v("这个功能是基于 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 实现的,默认支持以下三种类型的参数适配:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("Map")]),t._v(":参数将被适配为 "),a("code",[t._v("ConstantContainer")]),t._v(";")]),t._v(" "),a("li",[a("code",[t._v("Container")]),t._v(":直接使用;")]),t._v(" "),a("li",[a("code",[t._v("DataProvider")]),t._v(":参数将被适配为 "),a("code",[t._v("LambdaContainer")]),t._v(";")])]),t._v(" "),a("p",[t._v("如果有必要,用户还可以通过 "),a("code",[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" 的 "),a("code",[t._v("addAdaptorProvider")]),t._v(" 方法添加其他类型的参数适配器:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),t._v(" factory "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SpringUtil")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DynamicContainerOperatorProxyMethodFactory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将 LinkedHashMap 类型的参数适配为 ConstantContainer")]),t._v("\nfactory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addAdaptorProvider")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LinkedHashMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" parameter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("\n\targ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Containers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forMap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" arg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-4-指定执行器和解析器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-4-指定执行器和解析器"}},[t._v("#")]),t._v(" 3.7.4.指定执行器和解析器")]),t._v(" "),a("p",[t._v("类似于 "),a("code",[t._v("@AutoOperate")]),t._v(","),a("code",[t._v("@Operator")]),t._v(" 接口也可以指定用于执行操作的执行器和配置解析器。")]),t._v(" "),a("p",[t._v("比如:")]),t._v(" "),a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Operator")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n executorType "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderedBeanOperationExecutor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n parserType "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TypeHierarchyBeanOperationParser")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OperatorInterface")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Assemble")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" container "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" props "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Mapping")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("operate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Collection")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" targets"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"_3-7-5-代理方法工厂"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-7-5-代理方法工厂"}},[t._v("#")]),t._v(" 3.7.5.代理方法工厂")]),t._v(" "),a("p",[t._v("与 Spring 中将被 "),a("code",[t._v("@EventListener")]),t._v(" 注解的方法适配为监听器的模式类似,操作者接口中抽象方法的解析也是基于策略模式。")]),t._v(" "),a("p",[t._v("操作者的代理方法工厂 "),a("code",[t._v("OperatorProxyMethodFactory")]),t._v(" 默认提供了两种实现:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("DefaultProxyMethodFactory")]),t._v(":默认的代理方法工厂,支持处理所有有参方法;")]),t._v(" "),a("li",[a("code",[t._v("DynamicSourceProxyMethodFactory")]),t._v(":动态数据源方法工厂,用于支持有不止一个参数的方法;")])]),t._v(" "),a("p",[t._v("接口中的一个抽象方法仅会使用最匹配的工厂去生成代理方法。因此若有必要,用户也可以自行实现接口并提高工厂的优先级以替换默认策略。")]),t._v(" "),a("p",[t._v("在 Spring 环境中,只需将自定义工厂类声明为 Spring Bean,即可自动注册。在非 Spring 环境中,用户需要在创建代理工厂 "),a("code",[t._v("OperatorProxyFactory")]),t._v(" 时将所需的方法工厂作为参数传入。")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/46.cb03ac5c.js b/docs/assets/js/46.e568baf5.js similarity index 99% rename from docs/assets/js/46.cb03ac5c.js rename to docs/assets/js/46.e568baf5.js index 740b9158..30b79b8e 100644 --- a/docs/assets/js/46.cb03ac5c.js +++ b/docs/assets/js/46.e568baf5.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{322:function(_,v,t){"use strict";t.r(v);var r=t(14),e=Object(r.a)({},(function(){var _=this,v=_._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[v("p",[_._v("文档引用自:"),v("a",{attrs:{href:"https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way",target:"_blank",rel:"noopener noreferrer"}},[_._v("提问的智慧"),v("OutboundLink")],1)]),_._v(" "),v("h2",{attrs:{id:"在提问之前"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#在提问之前"}},[_._v("#")]),_._v(" 在提问之前")]),_._v(" "),v("p",[_._v("在你准备要通过电子邮件、新闻群组或者聊天室提出技术问题前,请先做到以下事情:")]),_._v(" "),v("ol",[v("li",[_._v("尝试在你准备提问的论坛的旧文章中搜索答案。")]),_._v(" "),v("li",[_._v("尝试上网搜索以找到答案。")]),_._v(" "),v("li",[_._v("尝试阅读手册以找到答案。")]),_._v(" "),v("li",[_._v("尝试阅读常见问题文件(FAQ)以找到答案。")]),_._v(" "),v("li",[_._v("尝试自己检查或试验以找到答案。")]),_._v(" "),v("li",[_._v("向你身边的强者朋友打听以找到答案。")]),_._v(" "),v("li",[_._v("如果你是程序开发者,请尝试阅读源代码以找到答案。")])]),_._v(" "),v("p",[_._v("当你提出问题的时候,请先表明你已经做了上述的努力;这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者。如果你能一并表达在做了上述努力的过程中所"),v("strong",[_._v("学到")]),_._v("的东西会更好,因为我们更乐于回答那些表现出能从答案中学习的人的问题。")]),_._v(" "),v("p",[_._v("运用某些策略,比如先用 Google 搜索你所遇到的各种错误信息(搜索 "),v("a",{attrs:{href:"http://groups.google.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google 论坛"),v("OutboundLink")],1),_._v("和网页),这样很可能直接就找到了能解决问题的文件或邮件列表线索。即使没有结果,在邮件列表或新闻组寻求帮助时加上一句 "),v("code",[_._v("我在 Google 中搜过下列句子但没有找到什么有用的东西")]),_._v(" 也是件好事,即使它只是表明了搜索引擎不能提供哪些帮助。这么做(加上搜索过的字串)也让遇到相似问题的其他人能被搜索引擎引导到你的提问来。")]),_._v(" "),v("p",[_._v("别着急,不要指望几秒钟的 Google 搜索就能解决一个复杂的问题。在向专家求助之前,再阅读一下常见问题文件(FAQ)、放轻松、坐得舒服一些,再花点时间思考一下这个问题。相信我们,他们能从你的提问看出你做了多少阅读与思考,如果你是有备而来,将更有可能得到解答。不要将所有问题一股脑拋出,只因你的第一次搜索没有找到答案(或者找到太多答案)。")]),_._v(" "),v("p",[_._v("准备好你的问题,再将问题仔细地思考过一遍,因为草率的发问只能得到草率的回答,或者根本得不到任何答案。越是能表现出在寻求帮助前你为解决问题所付出的努力,你越有可能得到实质性的帮助。")]),_._v(" "),v("p",[_._v("小心别问错了问题。如果你的问题基于错误的假设,某个普通黑客(J. Random Hacker)多半会一边在心里想着"),v("code",[_._v("蠢问题…")]),_._v(",一边用无意义的字面解释来答复你,希望着你会从问题的回答(而非你想得到的答案)中汲取教训。")]),_._v(" "),v("p",[_._v("绝不要自以为"),v("strong",[_._v("够格")]),_._v("得到答案,你没有;你并没有。毕竟你没有为这种服务支付任何报酬。你将会是自己去"),v("strong",[_._v("挣到")]),_._v("一个答案,靠提出有内涵的、有趣的、有思维激励作用的问题 —— 一个有潜力能贡献社区经验的问题,而不仅仅是被动地从他人处索取知识。")]),_._v(" "),v("p",[_._v("另一方面,表明你愿意在找答案的过程中做点什么是一个非常好的开端。"),v("code",[_._v("谁能给点提示?")]),_._v("、"),v("code",[_._v("我的这个例子里缺了什么?")]),_._v("以及"),v("code",[_._v("我应该检查什么地方")]),_._v("比"),v("code",[_._v("请把我需要的确切的过程贴出来")]),_._v("更容易得到答复。因为你表现出只要有人能指个正确方向,你就有完成它的能力和决心。")]),_._v(" "),v("h2",{attrs:{id:"当你提问时"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#当你提问时"}},[_._v("#")]),_._v(" 当你提问时")]),_._v(" "),v("h3",{attrs:{id:"慎选提问的论坛"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#慎选提问的论坛"}},[_._v("#")]),_._v(" 慎选提问的论坛")]),_._v(" "),v("p",[_._v("小心选择你要提问的场合。如果你做了下述的事情,你很可能被忽略掉或者被看作失败者:")]),_._v(" "),v("ul",[v("li",[_._v("在与主题不合的论坛上贴出你的问题。")]),_._v(" "),v("li",[_._v("在探讨进阶技术问题的论坛张贴非常初级的问题;反之亦然。")]),_._v(" "),v("li",[_._v("在太多的不同新闻群组上重复转贴同样的问题(cross-post)。")]),_._v(" "),v("li",[_._v("向既非熟人也没有义务解决你问题的人发送私人电邮。")])]),_._v(" "),v("p",[_._v("黑客会剔除掉那些搞错场合的问题,以保护他们沟通的渠道不被无关的东西淹没。你不会想让这种事发生在自己身上的。")]),_._v(" "),v("p",[_._v("因此,第一步是找到对的论坛。再说一次,Google 和其它搜索引擎还是你的朋友,用它们来找到与你遭遇到困难的软硬件问题最相关的网站。通常那儿都有常见问题(FAQ)、邮件列表及相关说明文件的链接。如果你的努力(包括"),v("strong",[_._v("阅读")]),_._v(" FAQ)都没有结果,网站上也许还有报告 Bug(Bug-reporting)的流程或链接,如果是这样,链过去看看。")]),_._v(" "),v("p",[_._v("向陌生的人或论坛发送邮件最可能是风险最大的事情。举例来说,别假设一个提供丰富内容的网页的作者会想充当你的免费顾问。不要对你的问题是否会受到欢迎做太乐观的估计 —— 如果你不确定,那就向别处发送,或者压根别发。")]),_._v(" "),v("p",[_._v("在选择论坛、新闻群组或邮件列表时,别太相信它的名字,先看看 FAQ 或者许可书以弄清楚你的问题是否切题。发文前先翻翻已有的话题,这样可以让你感受一下那里的文化。事实上,事先在新闻组或邮件列表的历史记录中搜索与你问题相关的关键词是个极好的主意,也许这样就找到答案了。即使没有,也能帮助你归纳出更好的问题。")]),_._v(" "),v("p",[_._v("别像机关枪似的一次“扫射”所有的帮助渠道,这就像大喊大叫一样会使人不快。要一个一个地来。")]),_._v(" "),v("p",[_._v("搞清楚你的主题!最典型的错误之一是在某种致力于跨平台可移植的语言、套件或工具的论坛中提关于 Unix 或 Windows 操作系统程序界面的问题。如果你不明白为什么这是大错,最好在搞清楚这之间差异之前什么也别问。")]),_._v(" "),v("p",[_._v("一般来说,在仔细挑选的公共论坛中提问,会比在私有论坛中提同样的问题更容易得到有用的回答。有几个理由可以支持这点,一是看潜在的回复者有多少,二是看观众有多少。黑客较愿意回答那些能帮助到许多人的问题。")]),_._v(" "),v("p",[_._v("可以理解的是,老练的黑客和一些热门软件的作者正在接受过多的错发信息。就像那根最后压垮骆驼背的稻草一样,你的加入也有可能使情况走向极端 —— 已经好几次了,一些热门软件的作者由于涌入其私人邮箱的大量不堪忍受的无用邮件而不再提供支持。")]),_._v(" "),v("h3",{attrs:{id:"stack-overflow"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#stack-overflow"}},[_._v("#")]),_._v(" Stack Overflow")]),_._v(" "),v("p",[_._v("搜索,"),v("em",[_._v("然后")]),_._v("在 Stack Exchange 问。")]),_._v(" "),v("p",[_._v("近年来,Stack Exchange 社区已经成为回答技术及其他问题的主要渠道,尤其是那些开放源码的项目。")]),_._v(" "),v("p",[_._v("因为 Google 索引是即时的,在看 Stack Exchange 之前先在 Google 搜索。有很高的几率某人已经问了一个类似的问题,而且 Stack Exchange 网站们往往会是搜索结果中最前面几个。如果你在 Google 上没有找到任何答案,你再到特定相关主题的网站去找。用标签(Tag)搜索能让你更缩小你的搜索结果。")]),_._v(" "),v("p",[_._v("如果你还是找不到任何对你的问题有用的内容,请把你的问题发在与它最相关的网站上。提问的时候请善用格式化工具,尤其注意为代码添加格式,并且添加相关的标签(特别是编程语言、操作系统或库/包的名称)。当有人要求你提供更多相关信息时,请编辑你的贴子来补充它们[译注:而不是发一个回帖或回答!]。如果你觉得一个答案对你有帮助,点击向上的箭头来为它投票;如果一个答案提供了问题的正确解决方案,点击投票按钮下方的对勾来将它标记为正解。")]),_._v(" "),v("p",[_._v("Stack Exchange 已经成长到"),v("a",{attrs:{href:"https://stackexchange.com/sites",target:"_blank",rel:"noopener noreferrer"}},[_._v("超过一百个网站"),v("OutboundLink")],1),_._v(",以下是最常用的几个站:")]),_._v(" "),v("ul",[v("li",[_._v("Super User 是问一些通用的电脑问题,如果你的问题跟代码或是写程序无关,只是一些网络连线之类的,请到这里。")]),_._v(" "),v("li",[_._v("Stack Overflow 是问写程序有关的问题。")]),_._v(" "),v("li",[_._v("Server Fault 是问服务器和网管相关的问题。")])]),_._v(" "),v("h3",{attrs:{id:"网站和-irc-论坛"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#网站和-irc-论坛"}},[_._v("#")]),_._v(" 网站和 IRC 论坛")]),_._v(" "),v("p",[_._v("本地的用户群组(user group),或者你所用的 Linux 发行版本也许正在宣传他们的网页论坛或 IRC 频道,并提供新手帮助(在一些非英语国家,新手论坛很可能还是邮件列表),这些都是开始提问的好地方,特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。有广告赞助的 IRC 频道是公开欢迎提问的地方,通常可以即时得到回应。")]),_._v(" "),v("p",[_._v("事实上,如果程序出的问题只发生在特定 Linux 发行版提供的版本(这很常见),最好先去该发行版的论坛或邮件列表中提问,再到程序本身的论坛或邮件列表提问。(否则)该项目的黑客可能仅仅回复“使用"),v("strong",[_._v("我们的")]),_._v("版本”。")]),_._v(" "),v("p",[_._v("在任何论坛发文以前,先确认一下有没有搜索功能。如果有,就试着搜索一下问题的几个关键词,也许这会有帮助。如果在此之前你已做过通用的网页搜索(你也该这样做),还是再搜索一下论坛,搜索引擎有可能没来得及索引此论坛的全部内容。")]),_._v(" "),v("p",[_._v("通过论坛或 IRC 频道来提供用户支持服务有增长的趋势,电子邮件则大多为项目开发者间的交流而保留。所以最好先在论坛或 IRC 中寻求与该项目相关的协助。")]),_._v(" "),v("p",[_._v("在使用 IRC 的时候,首先最好不要发布很长的问题描述,有些人称之为频道洪水。最好通过一句话的问题描述来开始聊天。")]),_._v(" "),v("h3",{attrs:{id:"第二步-使用项目邮件列表"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#第二步-使用项目邮件列表"}},[_._v("#")]),_._v(" 第二步,使用项目邮件列表")]),_._v(" "),v("p",[_._v("当某个项目提供开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。查一查项目的文件和首页,找到项目的邮件列表并使用它。有几个很好的理由支持我们采用这种办法:")]),_._v(" "),v("ul",[v("li",[_._v("任何好到需要向个别开发者提出的问题,也将对整个项目群组有益。反之,如果你认为自己的问题对整个项目群组来说太愚蠢,那这也不能成为骚扰个别开发者的理由。")]),_._v(" "),v("li",[_._v("向列表提问可以分散开发者的负担,个别开发者(尤其是项目领导人)也许太忙以至于没法回答你的问题。")]),_._v(" "),v("li",[_._v("大多数邮件列表都会被存档,那些被存档的内容将被搜索引擎索引。如果你向列表提问并得到解答,将来其他人可以通过网页搜索找到你的问题和答案,也就不用再次发问了。")]),_._v(" "),v("li",[_._v("如果某些问题经常被问到,开发者可以利用此信息来改进说明文件或软件本身,以使其更清楚。如果只是私下提问,就没有人能看到最常见问题的完整场景。")])]),_._v(" "),v("p",[_._v("如果一个项目既有“用户”也有“开发者”(或“黑客”)邮件列表或论坛,而你又不会动到那些源代码,那么就向“用户”列表或论坛提问。不要假设自己会在开发者列表中受到欢迎,那些人多半会将你的提问视为干扰他们开发的噪音。")]),_._v(" "),v("p",[_._v("然而,如果你"),v("strong",[_._v("确信")]),_._v("你的问题很特别,而且在“用户”列表或论坛中几天都没有回复,可以试试前往“开发者”列表或论坛发问。建议你在张贴前最好先暗地里观察几天以了解那里的行事方式(事实上这是参与任何私有或半私有列表的好主意)")]),_._v(" "),v("p",[_._v("如果你找不到一个项目的邮件列表,而只能查到项目维护者的电子邮件地址,尽管向他发信。即使是在这种情况下,也别假设(项目)邮件列表不存在。在你的电子邮件中,请陈述你已经试过但没有找到合适的邮件列表,也提及你不反对将自己的邮件转发给他人(许多人认为,即使没什么秘密,私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人,你给了相应人员处置你邮件的选择)。")]),_._v(" "),v("h3",{attrs:{id:"使用有意义且描述明确的标题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用有意义且描述明确的标题"}},[_._v("#")]),_._v(" 使用有意义且描述明确的标题")]),_._v(" "),v("p",[_._v("在邮件列表、新闻群组或论坛中,大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的"),v("code",[_._v("帮帮忙")]),_._v("、"),v("code",[_._v("跪求")]),_._v("、"),v("code",[_._v("急")]),_._v("(更别说"),v("code",[_._v("救命啊!!!!")]),_._v("这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动我们,而应该是在这点空间中使用极简单扼要的描述方式来提出问题。")]),_._v(" "),v("p",[_._v("一个好标题范例是"),v("code",[_._v("目标 —— 差异")]),_._v("式的描述,许多技术支持组织就是这样做的。在"),v("code",[_._v("目标")]),_._v("部分指出是哪一个或哪一组东西有问题,在"),v("code",[_._v("差异")]),_._v("部分则描述与期望的行为不一致的地方。")]),_._v(" "),v("blockquote",[v("p",[_._v("蠢问题:救命啊!我的笔记本电脑不能正常显示了!")])]),_._v(" "),v("blockquote",[v("p",[_._v("聪明问题:X.org 6.8.1 的鼠标指针会变形,某牌显卡 MV1005 芯片组。")])]),_._v(" "),v("blockquote",[v("p",[_._v("更聪明问题:X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。")])]),_._v(" "),v("p",[_._v("编写"),v("code",[_._v("目标 —— 差异")]),_._v(" 式描述的过程有助于你组织对问题的细致思考。是什么被影响了? 仅仅是鼠标指针或者还有其它图形?只在 X.org 的 X 版中出现?或只是出现在 6.8.1 版中? 是针对某牌显卡芯片组?或者只是其中的 MV1005 型号? 一个黑客只需瞄一眼就能够立即明白你的环境"),v("strong",[_._v("和")]),_._v("你遇到的问题。")]),_._v(" "),v("p",[_._v("总而言之,请想像一下你正在一个只显示标题的存档讨论串(Thread)索引中查寻。让你的标题更好地反映问题,可使下一个搜索类似问题的人能够关注这个讨论串,而不用再次提问相同的问题。")]),_._v(" "),v("p",[_._v("如果你想在回复中提出问题,记得要修改内容标题,以表明你是在问一个问题, 一个看起来像 "),v("code",[_._v("Re: 测试")]),_._v(" 或者 "),v("code",[_._v("Re: 新 bug")]),_._v(" 的标题很难引起足够重视。另外,在不影响连贯性之下,适当引用并删减前文的内容,能给新来的读者留下线索。")]),_._v(" "),v("p",[_._v("对于讨论串,不要直接点击回复来开始一个全新的讨论串,这将限制你的观众。因为有些邮件阅读程序,比如 mutt ,允许用户按讨论串排序并通过折叠讨论串来隐藏消息,这样做的人永远看不到你发的消息。")]),_._v(" "),v("p",[_._v("仅仅改变标题还不够。mutt 和其它一些邮件阅读程序还会检查邮件标题以外的其它信息,以便为其指定讨论串。所以宁可发一个全新的邮件。")]),_._v(" "),v("p",[_._v("在网页论坛上,好的提问方式稍有不同,因为讨论串与特定的信息紧密结合,并且通常在讨论串外就看不到里面的内容,故通过回复提问,而非改变标题是可接受的。不是所有论坛都允许在回复中出现分离的标题,而且这样做了基本上没有人会去看。不过,通过回复提问,这本身就是暧昧的做法,因为它们只会被正在查看该标题的人读到。所以,除非你"),v("strong",[_._v("只想")]),_._v("在该讨论串当前活跃的人群中提问,不然还是另起炉灶比较好。")]),_._v(" "),v("h3",{attrs:{id:"使问题容易回复"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使问题容易回复"}},[_._v("#")]),_._v(" 使问题容易回复")]),_._v(" "),v("p",[_._v("以"),v("code",[_._v("请将你的回复发送到……")]),_._v("来结束你的问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦,我们也觉得花几秒钟思考你的问题更麻烦。如果你的邮件程序不支持这样做,"),v("a",{attrs:{href:"http://linuxmafia.com/faq/Mail/muas.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("换个好点的"),v("OutboundLink")],1),_._v(";如果是操作系统不支持这种邮件程序,也换个好点的。")]),_._v(" "),v("p",[_._v("在论坛,要求通过电子邮件回复是非常无礼的,除非你认为回复的信息可能比较敏感(有人会为了某些未知的原因,只让你而不是整个论坛知道答案)。如果你只是想在有人回复讨论串时得到电子邮件提醒,可以要求网页论坛发送给你。几乎所有论坛都支持诸如"),v("code",[_._v("追踪此讨论串")]),_._v("、"),v("code",[_._v("有回复时发送邮件提醒")]),_._v("等功能。")]),_._v(" "),v("h3",{attrs:{id:"使用清晰、正确、精准且合乎语法的语句"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用清晰、正确、精准且合乎语法的语句"}},[_._v("#")]),_._v(" "),v("a",{attrs:{name:"使用清晰、正确、精准且合乎语法的语句"}},[_._v("使用清晰、正确、精准且合乎语法的语句")])]),_._v(" "),v("p",[_._v("我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。")]),_._v(" "),v("p",[_._v("正确的拼写、标点符号和大小写是很重要的。一般来说,如果你觉得这样做很麻烦,不想在乎这些,那我们也觉得麻烦,不想在乎你的提问。花点额外的精力斟酌一下字句,用不着太僵硬与正式 —— 事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它"),v("strong",[_._v("必须很")]),_._v("准确,而且有迹象表明你是在思考和关注问题。")]),_._v(" "),v("p",[_._v("正确地拼写、使用标点和大小写,不要将"),v("code",[_._v("its")]),_._v("混淆为"),v("code",[_._v("it's")]),_._v(","),v("code",[_._v("loose")]),_._v("搞成"),v("code",[_._v("lose")]),_._v("或者将"),v("code",[_._v("discrete")]),_._v("弄成"),v("code",[_._v("discreet")]),_._v("。不要"),v("strong",[_._v("全部用大写")]),_._v(",这会被视为无礼的大声嚷嚷(全部小写也好不到哪去,因为不易阅读。"),v("a",{attrs:{href:"http://en.wikipedia.org/wiki/Alan_Cox",target:"_blank",rel:"noopener noreferrer"}},[_._v("Alan Cox"),v("OutboundLink")],1),_._v(" 也许可以这样做,但你不行)。")]),_._v(" "),v("p",[_._v("更白话的说,如果你写得像是个半文盲[译注:"),v("a",{attrs:{href:"http://zh.wikipedia.org/wiki/%E5%B0%8F%E7%99%BD",target:"_blank",rel:"noopener noreferrer"}},[_._v("小白"),v("OutboundLink")],1),_._v("],那多半得不到理睬。也不要使用即时通信中的简写或"),v("a",{attrs:{href:"http://zh.wikipedia.org/wiki/%E7%81%AB%E6%98%9F%E6%96%87",target:"_blank",rel:"noopener noreferrer"}},[_._v("火星文"),v("OutboundLink")],1),_._v(",如将"),v("code",[_._v("的")]),_._v("简化为"),v("code",[_._v("d")]),_._v("会使你看起来像一个为了少打几个键而省字的小白。更糟的是,如果像个小孩似地鬼画符那绝对是在找死,可以肯定没人会理你(或者最多是给你一大堆指责与挖苦)。")]),_._v(" "),v("p",[_._v("如果在使用非母语的论坛提问,你可以犯点拼写和语法上的小错,但决不能在思考上马虎(没错,我们通常能弄清两者的分别)。同时,除非你知道回复者使用的语言,否则请使用英语书写。繁忙的黑客一般会直接删除用他们看不懂的语言写的消息。在网络上英语是通用语言,用英语书写可以将你的问题在尚未被阅读就被直接删除的可能性降到最低。")]),_._v(" "),v("p",[_._v("如果英文是你的外语(Second language),提示潜在回复者你有潜在的语言困难是很好的:\n[译注:以下附上原文以供使用]")]),_._v(" "),v("blockquote",[v("p",[_._v("English is not my native language; please excuse typing errors.")])]),_._v(" "),v("ul",[v("li",[_._v("英文不是我的母语,请原谅我的错字或语法。")])]),_._v(" "),v("blockquote",[v("p",[_._v("If you speak $LANGUAGE, please email/PM me;\nI may need assistance translating my question.")])]),_._v(" "),v("ul",[v("li",[_._v("如果你说"),v("strong",[_._v("某语言")]),_._v(",请向我发电邮/私信;")]),_._v(" "),v("li",[_._v("我需要有人协助我翻译我的问题。")])]),_._v(" "),v("blockquote",[v("p",[_._v("I am familiar with the technical terms,\nbut some slang expressions and idioms are difficult for me.")])]),_._v(" "),v("ul",[v("li",[_._v("我对技术名词很熟悉,但对于俗语或是特别用法不甚了解。")])]),_._v(" "),v("blockquote",[v("p",[_._v("I've posted my question in $LANGUAGE and English.\nI'll be glad to translate responses, if you only use one or the other.")])]),_._v(" "),v("ul",[v("li",[_._v("我把我的问题用"),v("strong",[_._v("某语言")]),_._v("和英文写出来。")]),_._v(" "),v("li",[_._v("如果你只用其中的一种语言回答,我会乐意将回复翻译成为你使用的语言。")])]),_._v(" "),v("h3",{attrs:{id:"使用易于读取且标准的文件格式发送问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用易于读取且标准的文件格式发送问题"}},[_._v("#")]),_._v(" 使用易于读取且标准的文件格式发送问题")]),_._v(" "),v("p",[_._v("如果你人为地将问题搞得难以阅读,它多半会被忽略,人们更愿读易懂的问题,所以:")]),_._v(" "),v("ul",[v("li",[_._v("使用纯文字而不是 HTML ("),v("a",{attrs:{href:"http://archive.birdhouse.org/etc/evilmail.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("关闭 HTML"),v("OutboundLink")],1),_._v(" 并不难)。")]),_._v(" "),v("li",[_._v("使用 MIME 附件通常是可以的,前提是真正有内容(譬如附带的源代码或 patch),而不仅仅是邮件程序生成的模板(譬如只是信件内容的拷贝)。")]),_._v(" "),v("li",[_._v("不要发送一段文字只是一行句子但自动换行后会变成多行的邮件(这使得回复部分内容非常困难)。设想你的读者是在 80 个字符宽的终端机上阅读邮件,最好设置你的换行分割点小于 80 字。")]),_._v(" "),v("li",[_._v("但是,对一些特殊的文件"),v("strong",[_._v("不要")]),_._v("设置固定宽度(譬如日志文件拷贝或会话记录)。数据应该原样包含,让回复者有信心他们看到的是和你看到的一样的东西。")]),_._v(" "),v("li",[_._v("在英语论坛中,不要使用"),v("code",[_._v("Quoted-Printable")]),_._v(" MIME 编码发送消息。这种编码对于张贴非 ASCII 语言可能是必须的,但很多邮件程序并不支持这种编码。当它们处理换行时,那些文本中四处散布的"),v("code",[_._v("=20")]),_._v("符号既难看也分散注意力,甚至有可能破坏内容的语意。")]),_._v(" "),v("li",[_._v("绝对,"),v("strong",[_._v("永远")]),_._v("不要指望黑客们阅读使用封闭格式编写的文档,像微软公司的 Word 或 Excel 文件等。大多数黑客对此的反应就像有人将还在冒热气的猪粪倒在你家门口时你的反应一样。即便他们能够处理,他们也很厌恶这么做。")]),_._v(" "),v("li",[_._v("如果你从使用 Windows 的电脑发送电子邮件,关闭微软愚蠢的"),v("code",[_._v("智能引号")]),_._v("功能 (从[选项] > [校订] > [自动校正选项],勾选掉"),v("code",[_._v("智能引号")]),_._v("单选框),以免在你的邮件中到处散布垃圾字符。")]),_._v(" "),v("li",[_._v("在论坛,勿滥用"),v("code",[_._v("表情符号")]),_._v("和"),v("code",[_._v("HTML")]),_._v("功能(当它们提供时)。一两个表情符号通常没有问题,但花哨的彩色文本倾向于使人认为你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来像个傻笑的小姑娘。这通常不是个好主意,除非你只是对性而不是对答案感兴趣。")])]),_._v(" "),v("p",[_._v("如果你使用图形用户界面的邮件程序(如微软公司的 Outlook 或者其它类似的),注意它们的默认设置不一定满足这些要求。大多数这类程序有基于选单的"),v("code",[_._v("查看源代码")]),_._v("命令,用它来检查发送文件夹中的邮件,以确保发送的是纯文本文件同时没有一些奇怪的字符。")]),_._v(" "),v("h3",{attrs:{id:"精确地描述问题并言之有物"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#精确地描述问题并言之有物"}},[_._v("#")]),_._v(" 精确地描述问题并言之有物")]),_._v(" "),v("ul",[v("li",[_._v("仔细、清楚地描述你的问题或 Bug 的症状。")]),_._v(" "),v("li",[_._v("描述问题发生的环境(机器配置、操作系统、应用程序、以及相关的信息),提供经销商的发行版和版本号(如:"),v("code",[_._v("Fedora Core 4")]),_._v("、"),v("code",[_._v("Slackware 9.1")]),_._v("等)。")]),_._v(" "),v("li",[_._v("描述在提问前你是怎样去研究和理解这个问题的。")]),_._v(" "),v("li",[_._v("描述在提问前为确定问题而采取的诊断步骤。")]),_._v(" "),v("li",[_._v("描述最近做过什么可能相关的硬件或软件变更。")]),_._v(" "),v("li",[_._v("尽可能地提供一个可以"),v("code",[_._v("重现这个问题的可控环境")]),_._v("的方法。")])]),_._v(" "),v("p",[_._v("尽量去揣测一个黑客会怎样反问你,在你提问之前预先将黑客们可能提出的问题回答一遍。")]),_._v(" "),v("p",[_._v("以上几点中,当你报告的是你认为可能在代码中的问题时,给黑客一个可以重现你的问题的环境尤其重要。当你这么做时,你得到有效的回答的机会和速度都会大大的提升。")]),_._v(" "),v("p",[v("a",{attrs:{href:"http://www.chiark.greenend.org.uk/~sgtatham/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Simon Tatham"),v("OutboundLink")],1),_._v(" 写过一篇名为《"),v("a",{attrs:{href:"http://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("如何有效的报告 Bug"),v("OutboundLink")],1),_._v("》的出色文章。强力推荐你也读一读。")]),_._v(" "),v("h3",{attrs:{id:"话不在多而在精"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#话不在多而在精"}},[_._v("#")]),_._v(" 话不在多而在精")]),_._v(" "),v("p",[_._v("你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全转录到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境,尽量将它剪裁得越小越好。")]),_._v(" "),v("p",[_._v("这样做的用处至少有三点。\n第一,表现出你为简化问题付出了努力,这可以使你得到回答的机会增加;\n第二,简化问题使你更有可能得到"),v("strong",[_._v("有用")]),_._v("的答案;\n第三,在精炼你的 bug 报告的过程中,你很可能就自己找到了解决方法或权宜之计。")]),_._v(" "),v("h3",{attrs:{id:"别动辄声称找到-bug"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别动辄声称找到-bug"}},[_._v("#")]),_._v(" 别动辄声称找到 Bug")]),_._v(" "),v("p",[_._v("当你在使用软件中遇到问题,除非你非常、"),v("strong",[_._v("非常")]),_._v("的有根据,不要动辄声称找到了 Bug。提示:除非你能提供解决问题的源代码补丁,或者提供回归测试来表明前一版本中行为不正确,否则你都多半不够完全确信。这同样适用在网页和文件,如果你(声称)发现了文件的"),v("code",[_._v("Bug")]),_._v(",你应该能提供相应位置的修正或替代文件。")]),_._v(" "),v("p",[_._v("请记得,还有其他许多用户没遇到你发现的问题,否则你在阅读文件或搜索网页时就应该发现了(你在抱怨前"),v("a",{attrs:{href:"#%E5%9C%A8%E6%8F%90%E9%97%AE%E4%B9%8B%E5%89%8D"}},[_._v("已经做了这些,是吧")]),_._v("?)。这也意味着很有可能是你弄错了而不是软件本身有问题。")]),_._v(" "),v("p",[_._v("编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了 Bug,也就是在质疑他们的能力,即使你是对的,也有可能会冒犯到其中某部分人。当你在标题中嚷嚷着有"),v("code",[_._v("Bug")]),_._v("时,这尤其严重。")]),_._v(" "),v("p",[_._v("提问时,即使你私下非常确信已经发现一个真正的 Bug,最好写得像是"),v("strong",[_._v("你")]),_._v("做错了什么。如果真的有 Bug,你会在回复中看到这点。这样做的话,如果真有 Bug,维护者就会向你道歉,这总比你惹恼别人然后欠别人一个道歉要好一点。")]),_._v(" "),v("h3",{attrs:{id:"低声下气不能代替你的功课"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#低声下气不能代替你的功课"}},[_._v("#")]),_._v(" 低声下气不能代替你的功课")]),_._v(" "),v("p",[_._v("有些人明白他们不该粗鲁或傲慢的提问并要求得到答复,但他们选择另一个极端 —— 低声下气:"),v("code",[_._v("我知道我只是个可悲的新手,一个撸瑟,但...")]),_._v("。这既使人困扰,也没有用,尤其是伴随着与实际问题含糊不清的描述时更令人反感。")]),_._v(" "),v("p",[_._v("别用原始灵长类动物的把戏来浪费你我的时间。取而代之的是,尽可能清楚地描述背景条件和你的问题情况。这比低声下气更好地定位了你的位置。")]),_._v(" "),v("p",[_._v("有时网页论坛会设有专为新手提问的版面,如果你真的认为遇到了初学者的问题,到那去就是了,但一样别那么低声下气。")]),_._v(" "),v("h3",{attrs:{id:"描述问题症状而非你的猜测"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#描述问题症状而非你的猜测"}},[_._v("#")]),_._v(" 描述问题症状而非你的猜测")]),_._v(" "),v("p",[_._v("告诉黑客们你认为问题是怎样造成的并没什么帮助。(如果你的推断如此有效,还用向别人求助吗?),因此要确信你原原本本告诉了他们问题的症状,而不是你的解释和理论;让黑客们来推测和诊断。如果你认为陈述自己的猜测很重要,清楚地说明这只是你的猜测,并描述为什么它们不起作用。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我在编译内核时接连遇到 SIG11 错误,\n我怀疑某条飞线搭在主板的走线上了,这种情况应该怎样检查最好?")])]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU(威盛 Apollo VP2 芯片组),\n256MB Corsair PC133 SDRAM 内存,在编译内核时,从开机 20 分钟以后就频频产生 SIG11 错误,\n但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用,但是关机一晚上就又能工作 20 分钟。\n所有内存都换过了,没有效果。相关部分的标准编译记录如下…")])]),_._v(" "),v("p",[_._v("由于以上这点似乎让许多人觉得难以配合,这里有句话可以提醒你:"),v("code",[_._v("所有的诊断专家都来自密苏里州。")]),_._v(" 美国国务院的官方座右铭则是:"),v("code",[_._v("让我看看")]),_._v("(出自国会议员 Willard D. Vandiver 在 1899 年时的讲话:"),v("code",[_._v("我来自一个出产玉米,棉花,牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。")]),_._v(") 针对诊断者而言,这并不是一种怀疑,而只是一种真实而有用的需求,以便让他们看到的是与你看到的原始证据尽可能一致的东西,而不是你的猜测与归纳的结论。所以,大方地展示给我们看吧!")]),_._v(" "),v("h3",{attrs:{id:"按发生时间先后列出问题症状"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#按发生时间先后列出问题症状"}},[_._v("#")]),_._v(" 按发生时间先后列出问题症状")]),_._v(" "),v("p",[_._v("问题发生前的一系列操作,往往就是对找出问题最有帮助的线索。因此,你的说明里应该包含你的操作步骤,以及机器和软件的反应,直到问题发生。在命令行处理的情况下,提供一段操作记录(例如运行脚本工具所生成的),并引用相关的若干行(如 20 行)记录会非常有帮助。")]),_._v(" "),v("p",[_._v("如果挂掉的程序有诊断选项(如 -v 的详述开关),试着选择这些能在记录中增加调试信息的选项。记住,"),v("code",[_._v("多")]),_._v("不等于"),v("code",[_._v("好")]),_._v("。试着选取适当的调试级别以便提供有用的信息而不是让读者淹没在垃圾中。")]),_._v(" "),v("p",[_._v("如果你的说明很长(如超过四个段落),在开头简述问题,接下来再按时间顺序详述会有所帮助。这样黑客们在读你的记录时就知道该注意哪些内容了。")]),_._v(" "),v("h3",{attrs:{id:"描述目标而不是过程"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#描述目标而不是过程"}},[_._v("#")]),_._v(" 描述目标而不是过程")]),_._v(" "),v("p",[_._v("如果你想弄清楚如何做某事(而不是报告一个 Bug),在开头就描述你的目标,然后才陈述重现你所卡住的特定步骤。")]),_._v(" "),v("p",[_._v("经常寻求技术帮助的人在心中有个更高层次的目标,而他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我怎样才能从某绘图程序的颜色选择器中取得十六进制的 RGB 值?")])]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我正试着用替换一幅图片的色码(color table)成自己选定的色码,我现在知道的唯一方法是编辑每个色码区块(table slot),\n但却无法从某绘图程序的颜色选择器取得十六进制的 RGB 值。")])]),_._v(" "),v("p",[_._v("第二种提问法比较聪明,你可能得到像是"),v("code",[_._v("建议采用另一个更合适的工具")]),_._v("的回复。")]),_._v(" "),v("h3",{attrs:{id:"别要求使用私人电邮回复"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别要求使用私人电邮回复"}},[_._v("#")]),_._v(" 别要求使用私人电邮回复")]),_._v(" "),v("p",[_._v("黑客们认为问题的解决过程应该公开、透明,此过程中如果更有经验的人注意到不完整或者不当之处,最初的回复才能够、也应该被纠正。同时,作为提供帮助者可以得到一些奖励,奖励就是他的能力和学识被其他同行看到。")]),_._v(" "),v("p",[_._v("当你要求私下回复时,这个过程和奖励都被中止。别这样做,让"),v("strong",[_._v("回复者")]),_._v("来决定是否私下回答 —— 如果他真这么做了,通常是因为他认为问题编写太差或者太肤浅,以至于不可能使其他人产生兴趣。")]),_._v(" "),v("p",[_._v("这条规则存在一条有限的例外,如果你确信提问可能会引来大量雷同的回复时,那么这个神奇的提问句会是"),v("code",[_._v("向我发电邮,我将为论坛归纳这些回复")]),_._v("。试着将邮件列表或新闻群组从洪水般的雷同回复中解救出来是非常有礼貌的 —— 但你必须信守诺言。")]),_._v(" "),v("h3",{attrs:{id:"清楚明确地表达你的问题以及需求"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#清楚明确地表达你的问题以及需求"}},[_._v("#")]),_._v(" 清楚明确地表达你的问题以及需求")]),_._v(" "),v("p",[_._v("漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人(他们忙是因为要亲自完成大部分工作)。这样的人对无节制的时间黑洞相当厌恶,所以他们也倾向于厌恶那些漫无边际的提问。")]),_._v(" "),v("p",[_._v("如果你明确表述需要回答者做什么(如提供指点、发送一段代码、检查你的补丁、或是其他等等),就最有可能得到有用的答案。因为这会定出一个时间和精力的上限,便于回答者能集中精力来帮你。这么做很棒。")]),_._v(" "),v("p",[_._v("要理解专家们所处的世界,请把专业技能想像为充裕的资源,而回复的时间则是稀缺的资源。你要求他们奉献的时间越少,你越有可能从真正专业而且很忙的专家那里得到解答。")]),_._v(" "),v("p",[_._v("所以,界定一下你的问题,使专家花在辨识你的问题和回答所需要付出的时间减到最少,这技巧对你获得有用的答案相当有帮助 —— 但这技巧通常和简化问题有所区别。因此,问"),v("code",[_._v("我想更好地理解 X,可否指点一下哪有好一点说明?")]),_._v("通常比问"),v("code",[_._v("你能解释一下 X 吗?")]),_._v("更好。如果你的代码不能运作,通常请别人看看哪里有问题,比要求别人替你改正要明智得多。")]),_._v(" "),v("h3",{attrs:{id:"询问有关代码的问题时"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#询问有关代码的问题时"}},[_._v("#")]),_._v(" 询问有关代码的问题时")]),_._v(" "),v("p",[_._v("如果没有提示别人应该从何入手,别要求他人帮你调试有问题的代码。张贴几百行的代码,然后说一声:"),v("code",[_._v("它不能工作")]),_._v("会让你完全被忽略。只贴几十行代码,然后说一句:"),v("code",[_._v("在第七行以后,我期待它显示 ,但实际出现的是 ")]),_._v("比较有可能让你得到回应。")]),_._v(" "),v("p",[_._v("最有效描述程序问题的方法是提供最精简的 Bug 展示测试用例(bug-demonstrating test case)。什么是最精简的测试用例?那是问题的缩影;一小个程序片段能"),v("strong",[_._v("刚好")]),_._v("展示出程序的异常行为,而不包含其他令人分散注意力的内容。怎么制作最精简的测试用例?如果你知道哪一行或哪一段代码会造成异常的行为,复制下来并加入足够重现这个状况的代码(例如,足以让这段代码能被编译/直译/被应用程序处理)。如果你无法将问题缩减到一个特定区块,就复制一份代码并移除不影响产生问题行为的部分。总之,测试用例越小越好(查看"),v("a",{attrs:{href:"#%E8%AF%9D%E4%B8%8D%E5%9C%A8%E5%A4%9A%E8%80%8C%E5%9C%A8%E7%B2%BE"}},[_._v("话不在多而在精")]),_._v("一节)。")]),_._v(" "),v("p",[_._v("一般而言,要得到一段相当精简的测试用例并不太容易,但永远先尝试这样做是一个好习惯。这种方式可以帮助你了解如何自行解决这个问题 —— 而且即使你的尝试不成功,黑客们也会看到你在尝试取得答案的过程中付出了努力,这可以让他们更愿意与你合作。")]),_._v(" "),v("p",[_._v("如果你只是想让别人帮忙审查(Review)一下代码,在信的开头就要说出来,并且一定要提到你认为哪一部分特别需要关注以及为什么。")]),_._v(" "),v("h3",{attrs:{id:"别把自己家庭作业的问题贴上来"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别把自己家庭作业的问题贴上来"}},[_._v("#")]),_._v(" 别把自己家庭作业的问题贴上来")]),_._v(" "),v("p",[_._v("黑客们很擅长分辨哪些问题是家庭作业式的问题;因为我们中的大多数都曾自己解决这类问题。同样,这些问题得由"),v("strong",[_._v("你")]),_._v("来搞定,你会从中学到东西。你可以要求给点提示,但别要求得到完整的解决方案。")]),_._v(" "),v("p",[_._v("如果你怀疑自己碰到了一个家庭作业式的问题,但仍然无法解决,试试在用户群组,论坛或(最后一招)在项目的"),v("strong",[_._v("用户")]),_._v("邮件列表或论坛中提问。尽管黑客们"),v("strong",[_._v("会")]),_._v("看出来,但一些有经验的用户也许仍会给你一些提示。")]),_._v(" "),v("h3",{attrs:{id:"去掉无意义的提问句"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#去掉无意义的提问句"}},[_._v("#")]),_._v(" 去掉无意义的提问句")]),_._v(" "),v("p",[_._v("避免用无意义的话结束提问,例如"),v("code",[_._v("有人能帮我吗?")]),_._v("或者"),v("code",[_._v("这有答案吗?")]),_._v("。")]),_._v(" "),v("p",[_._v("首先:如果你对问题的描述不是很好,这样问更是画蛇添足。")]),_._v(" "),v("p",[_._v("其次:由于这样问是画蛇添足,黑客们会很厌烦你 —— 而且通常会用逻辑上正确,但毫无意义的回答来表示他们的蔑视, 例如:"),v("code",[_._v("没错,有人能帮你")]),_._v("或者"),v("code",[_._v("不,没答案")]),_._v("。")]),_._v(" "),v("p",[_._v("一般来说,避免用 "),v("code",[_._v("是或否")]),_._v("、"),v("code",[_._v("对或错")]),_._v("、"),v("code",[_._v("有或没有")]),_._v("类型的问句,除非你想得到"),v("a",{attrs:{href:"https://strcat.de/questions-with-yes-or-no-answers.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("是或否类型的回答"),v("OutboundLink")],1),_._v("。")]),_._v(" "),v("h3",{attrs:{id:"即使你很急也不要在标题写紧急"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#即使你很急也不要在标题写紧急"}},[_._v("#")]),_._v(" 即使你很急也不要在标题写"),v("code",[_._v("紧急")])]),_._v(" "),v("p",[_._v("这是你的问题,不是我们的。宣称"),v("code",[_._v("紧急")]),_._v("极有可能事与愿违:大多数黑客会直接删除无礼和自私地企图即时引起关注的问题。更严重的是,"),v("code",[_._v("紧急")]),_._v("这个字(或是其他企图引起关注的标题)通常会被垃圾信过滤器过滤掉 —— 你希望能看到你问题的人可能永远也看不到。")]),_._v(" "),v("p",[_._v("有半个例外的情况是,如果你是在一些很高调,会使黑客们兴奋的地方,也许值得这样去做。在这种情况下,如果你有时间压力,也很有礼貌地提到这点,人们也许会有兴趣回答快一点。")]),_._v(" "),v("p",[_._v("当然,这风险很大,因为黑客们兴奋的点多半与你的不同。譬如从 NASA 国际空间站(International Space Station)发这样的标题没有问题,但用自我感觉良好的慈善行为或政治原因发肯定不行。事实上,张贴诸如"),v("code",[_._v("紧急:帮我救救这个毛茸茸的小海豹!")]),_._v("肯定让你被黑客忽略或惹恼他们,即使他们认为毛茸茸的小海豹很重要。")]),_._v(" "),v("p",[_._v("如果你觉得这点很不可思议,最好再把这份指南剩下的内容多读几遍,直到你弄懂了再发文。")]),_._v(" "),v("h3",{attrs:{id:"礼多人不怪-而且有时还很有帮助"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#礼多人不怪-而且有时还很有帮助"}},[_._v("#")]),_._v(" 礼多人不怪,而且有时还很有帮助")]),_._v(" "),v("p",[_._v("彬彬有礼,多用"),v("code",[_._v("请")]),_._v("和"),v("code",[_._v("谢谢您的关注")]),_._v(",或"),v("code",[_._v("谢谢你的关照")]),_._v("。让大家都知道你对他们花时间免费提供帮助心存感激。")]),_._v(" "),v("p",[_._v("坦白说,这一点并没有比使用清晰、正确、精准且合乎语法和避免使用专用格式重要(也不能取而代之)。黑客们一般宁可读有点唐突但技术上鲜明的 Bug 报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教给我们什么来评价问题的价值的)")]),_._v(" "),v("p",[_._v("然而,如果你有一串的问题待解决,客气一点肯定会增加你得到有用回应的机会。")]),_._v(" "),v("p",[_._v("(我们注意到,自从本指南发布后,从资深黑客那里得到的唯一严重缺陷反馈,就是对预先道谢这一条。一些黑客觉得"),v("code",[_._v("先谢了")]),_._v("意味着事后就不用再感谢任何人的暗示。我们的建议是要么先说"),v("code",[_._v("先谢了")]),_._v(","),v("strong",[_._v("然后")]),_._v("事后再对回复者表示感谢,或者换种方式表达感激,譬如用"),v("code",[_._v("谢谢你的关注")]),_._v("或"),v("code",[_._v("谢谢你的关照")]),_._v("。)")]),_._v(" "),v("h3",{attrs:{id:"问题解决后-加个简短的补充说明"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#问题解决后-加个简短的补充说明"}},[_._v("#")]),_._v(" 问题解决后,加个简短的补充说明")]),_._v(" "),v("p",[_._v("问题解决后,向所有帮助过你的人发个说明,让他们知道问题是怎样解决的,并再一次向他们表示感谢。如果问题在新闻组或者邮件列表中引起了广泛关注,应该在那里贴一个说明比较恰当。")]),_._v(" "),v("p",[_._v("最理想的方式是向最初提问的话题回复此消息,并在标题中包含"),v("code",[_._v("已修正")]),_._v(","),v("code",[_._v("已解决")]),_._v("或其它同等含义的明显标记。在人来人往的邮件列表里,一个看见讨论串"),v("code",[_._v("问题 X")]),_._v("和"),v("code",[_._v("问题 X - 已解决")]),_._v("的潜在回复者就明白不用再浪费时间了(除非他个人觉得"),v("code",[_._v("问题 X")]),_._v("有趣),因此可以利用此时间去解决其它问题。")]),_._v(" "),v("p",[_._v("补充说明不必很长或是很深入;简单的一句"),v("code",[_._v("你好,原来是网线出了问题!谢谢大家 – Bill")]),_._v("比什么也不说要来的好。事实上,除非结论真的很有技术含量,否则简短可爱的小结比长篇大论更好。说明问题是怎样解决的,但大可不必将解决问题的过程复述一遍。")]),_._v(" "),v("p",[_._v("对于有深度的问题,张贴调试记录的摘要是有帮助的。描述问题的最终状态,说明是什么解决了问题,在此"),v("strong",[_._v("之后")]),_._v("才指明可以避免的盲点。避免盲点的部分应放在正确的解决方案和其它总结材料之后,而不要将此信息搞成侦探推理小说。列出那些帮助过你的名字,会让你交到更多朋友。")]),_._v(" "),v("p",[_._v("除了有礼貌和有内涵以外,这种类型的补充也有助于他人在邮件列表/新闻群组/论坛中搜索到真正解决你问题的方案,让他们也从中受益。")]),_._v(" "),v("p",[_._v("至少,这种补充有助于让每位参与协助的人因问题的解决而从中得到满足感。如果你自己不是技术专家或者黑客,那就相信我们,这种感觉对于那些你向他们求助的大师或者专家而言,是非常重要的。问题悬而未决会让人灰心;黑客们渴望看到问题被解决。好人有好报,满足他们的渴望,你会在下次提问时尝到甜头。")]),_._v(" "),v("p",[_._v("思考一下怎样才能避免他人将来也遇到类似的问题,自问写一份文件或加个常见问题(FAQ)会不会有帮助。如果是的话就将它们发给维护者。")]),_._v(" "),v("p",[_._v("在黑客中,这种良好的后继行动实际上比传统的礼节更为重要,也是你如何透过善待他人而赢得声誉的方式,这是非常有价值的资产。")]),_._v(" "),v("h2",{attrs:{id:"如何解读答案"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何解读答案"}},[_._v("#")]),_._v(" 如何解读答案")]),_._v(" "),v("p",[v("a",{attrs:{id:"rtfm"}})]),_._v(" "),v("h3",{attrs:{id:"rtfm-和-stfw-如何知道你已完全搞砸了"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#rtfm-和-stfw-如何知道你已完全搞砸了"}},[_._v("#")]),_._v(" RTFM 和 STFW:如何知道你已完全搞砸了")]),_._v(" "),v("p",[_._v("有一个古老而神圣的传统:如果你收到"),v("code",[_._v("RTFM(Read The Fucking Manual)")]),_._v("的回应,回答者认为你"),v("strong",[_._v("应该去读他妈的手册")]),_._v("。当然,基本上他是对的,你应该去读一读。")]),_._v(" "),v("p",[_._v("RTFM 有一个年轻的亲戚。如果你收到"),v("code",[_._v("STFW(Search The Fucking Web)")]),_._v("的回应,回答者认为你"),v("strong",[_._v("应该到他妈的网上搜索")]),_._v("。那人多半也是对的,去搜索一下吧。(更温和一点的说法是 "),v("strong",[v("a",{attrs:{href:"http://lmgtfy.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google 是你的朋友"),v("OutboundLink")],1)]),_._v("!)")]),_._v(" "),v("p",[_._v("在论坛,你也可能被要求去爬爬论坛的旧文。事实上,有人甚至可能热心地为你提供以前解决此问题的讨论串。但不要依赖这种关照,提问前应该先搜索一下旧文。")]),_._v(" "),v("p",[_._v("通常,用这两句之一回答你的人会给你一份包含你需要内容的手册或者一个网址,而且他们打这些字的时候也正在读着。这些答复意味着回答者认为:")]),_._v(" "),v("ul",[v("li",[v("strong",[_._v("你需要的信息非常容易获得")]),_._v(";")]),_._v(" "),v("li",[v("strong",[_._v("你自己去搜索这些信息比灌给你,能让你学到更多")]),_._v("。")])]),_._v(" "),v("p",[_._v("你不应该因此不爽;"),v("strong",[_._v("依照黑客的标准,他已经表示了对你一定程度的关注,而没有对你的要求视而不见")]),_._v("。你应该对他祖母般的慈祥表示感谢。")]),_._v(" "),v("h3",{attrs:{id:"如果还是搞不懂"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如果还是搞不懂"}},[_._v("#")]),_._v(" 如果还是搞不懂")]),_._v(" "),v("p",[_._v("如果你看不懂回应,别立刻要求对方解释。像你以前试着自己解决问题时那样(利用手册,FAQ,网络,身边的高手),先试着去搞懂他的回应。如果你真的需要对方解释,记得表现出你已经从中学到了点什么。")]),_._v(" "),v("p",[_._v("比方说,如果我回答你:"),v("code",[_._v("看来似乎是 zentry 卡住了;你应该先清除它。")]),_._v(",然后,这是一个"),v("strong",[_._v("很糟的")]),_._v("后续问题回应:"),v("code",[_._v("zentry 是什么?")]),_._v(" "),v("strong",[_._v("好")]),_._v("的问法应该是这样:"),v("code",[_._v("哦~~~我看过说明了但是只有 -z 和 -p 两个参数中提到了 zentries,而且还都没有清楚的解释如何清除它。你是指这两个中的哪一个吗?还是我看漏了什么?")])]),_._v(" "),v("h3",{attrs:{id:"处理无礼的回应"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#处理无礼的回应"}},[_._v("#")]),_._v(" 处理无礼的回应")]),_._v(" "),v("p",[_._v("很多黑客圈子中看似无礼的行为并不是存心冒犯。相反,它是直截了当,一针见血式的交流风格,这种风格更注重解决问题,而不是使人感觉舒服而却模模糊糊。")]),_._v(" "),v("p",[_._v("如果你觉得被冒犯了,试着平静地反应。如果有人真的做了出格的事,邮件列表、新闻群组或论坛中的前辈多半会招呼他。如果这"),v("strong",[_._v("没有")]),_._v("发生而你却发火了,那么你发火对象的言语可能在黑客社区中看起来是正常的,而"),v("strong",[_._v("你")]),_._v("将被视为有错的一方,这将伤害到你获取信息或帮助的机会。")]),_._v(" "),v("p",[_._v("另一方面,你偶尔真的会碰到无礼和无聊的言行。与上述相反,对真正的冒犯者狠狠地打击,用犀利的语言将其驳得体无完肤都是可以接受的。然而,在行事之前一定要非常非常的有根据。纠正无礼的言论与开始一场毫无意义的口水战仅一线之隔,黑客们自己莽撞地越线的情况并不鲜见。如果你是新手或外人,避开这种莽撞的机会并不高。如果你想得到的是信息而不是消磨时光,这时最好不要把手放在键盘上以免冒险。")]),_._v(" "),v("p",[_._v("(有些人断言很多黑客都有轻度的自闭症或亚斯伯格综合症,缺少用于润滑人类社会"),v("strong",[_._v("正常")]),_._v("交往所需的神经。这既可能是真也可能是假的。如果你自己不是黑客,兴许你认为我们脑袋有问题还能帮助你应付我们的古怪行为。只管这么干好了,我们不在乎。我们"),v("strong",[_._v("喜欢")]),_._v("我们现在这个样子,并且通常对病患标记都有站得住脚的怀疑。)")]),_._v(" "),v("p",[_._v("Jeff Bigler 的观察总结和这个相关也值得一读 ("),v("strong",[v("a",{attrs:{href:"http://www.mit.edu/~jcb/tact.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("tact filters"),v("OutboundLink")],1)]),_._v(")。")]),_._v(" "),v("p",[_._v("在下一节,我们会谈到另一个问题,当"),v("strong",[_._v("你")]),_._v("行为不当时所会受到的"),v("code",[_._v("冒犯")]),_._v("。")]),_._v(" "),v("h2",{attrs:{id:"如何避免扮演失败者"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何避免扮演失败者"}},[_._v("#")]),_._v(" 如何避免扮演失败者")]),_._v(" "),v("p",[_._v("在黑客社区的论坛中,你以本指南所描述的或类似的方式,可能会有那么几次搞砸了。而你会在公开场合中被告知你是如何搞砸的,也许攻击的言语中还会带点夹七夹八的颜色。")]),_._v(" "),v("p",[_._v("这种事发生以后,你能做的最糟糕的事莫过于哀嚎你的遭遇、宣称被言语攻击、要求道歉、高声尖叫、憋闷气、威胁诉诸法律、向其雇主报怨、不去关马桶盖等等。相反地,你该这么做:")]),_._v(" "),v("p",[_._v("熬过去,这很正常。事实上,它是有益健康且合理的。")]),_._v(" "),v("p",[_._v("社区的标准不会自行维持,它们是通过参与者积极而"),v("strong",[_._v("公开地")]),_._v("执行来维持的。不要哭嚎所有的批评都应该通过私下的邮件传送,它不是这样运作的。当有人评论你的一个说法有误或者提出不同看法时,坚持声称受到个人攻击也毫无益处,这些都是失败者的态度。")]),_._v(" "),v("p",[_._v("也有其它的黑客论坛,受过高礼节要求的误导,禁止参与者张贴任何对别人帖子挑毛病的消息,并声称"),v("code",[_._v("如果你不想帮助用户就闭嘴。")]),_._v(" 结果造成有想法的参与者纷纷离开,这么做只会使它们沦为毫无意义的唠叨与无用的技术论坛。")]),_._v(" "),v("p",[_._v("夸张的讲法是:你要的是“友善”(以上述方式)还是有用?两个里面挑一个。")]),_._v(" "),v("p",[_._v("记着:当黑客说你搞砸了,并且(无论多么刺耳)告诉你别再这样做时,他正在为关心"),v("strong",[_._v("你")]),_._v("和"),v("strong",[_._v("他的社区")]),_._v("而行动。对他而言,不理你并将你从他的生活中滤掉更简单。如果你无法做到感谢,至少要表现得有点尊严,别大声哀嚎,也别因为自己是个有戏剧性超级敏感的灵魂和自以为有资格的新来者,就指望别人像对待脆弱的洋娃娃那样对你。")]),_._v(" "),v("p",[_._v("有时候,即使你没有搞砸(或者只是在他的想像中你搞砸了),有些人也会无缘无故地攻击你本人。在这种情况下,抱怨倒是"),v("strong",[_._v("真的")]),_._v("会把问题搞砸。")]),_._v(" "),v("p",[_._v("这些来找麻烦的人要么是毫无办法但自以为是专家的不中用家伙,要么就是测试你是否真会搞砸的心理专家。其它读者要么不理睬,要么用自己的方式对付他们。这些来找麻烦的人在给他们自己找麻烦,这点你不用操心。")]),_._v(" "),v("p",[_._v("也别让自己卷入口水战,最好不要理睬大多数的口水战 —— 当然,这是在你检验它们只是口水战,并且未指出你有搞砸的地方,同时也没有巧妙地将问题真正的答案藏于其后(这也是有可能的)。")]),_._v(" "),v("h2",{attrs:{id:"不该问的问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#不该问的问题"}},[_._v("#")]),_._v(" 不该问的问题")]),_._v(" "),v("p",[_._v("以下是几个经典蠢问题,以及黑客没回答时心中所想的:")]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q1"}},[_._v("我能在哪找到 X 程序或 X 资源?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q2"}},[_._v("我怎样用 X 做 Y?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q3"}},[_._v("如何设定我的 shell 提示?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q4"}},[_._v("我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文件转换为 TeX 格式吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q5"}},[_._v("我的程序/设定/SQL 语句没有用")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q6"}},[_._v("我的 Windows 电脑有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q7"}},[_._v("我的程序不会动了,我认为系统工具 X 有问题")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q8"}},[_._v("我在安装 Linux(或者 X )时有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q9"}},[_._v("我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?")])]),_._v(" "),v("hr"),_._v(" "),v("p",[v("a",{attrs:{id:"q1"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我能在哪找到 X 程序或 X 资源?")])]),_._v(" "),v("p",[_._v("回答:就在我找到它的地方啊,白痴 —— 搜索引擎的那一头。天哪!难道还有人不会用 "),v("a",{attrs:{href:"https://www.google.com",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google"),v("OutboundLink")],1),_._v(" 吗?")]),_._v(" "),v("p",[v("a",{attrs:{id:"q2"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我怎样用 X 做 Y?")])]),_._v(" "),v("p",[_._v("回答:如果你想解决的是 Y ,提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知,也对 Y 要解决的问题糊涂,还被特定形势禁锢了思维。最好忽略这种人,等他们把问题搞清楚了再说。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q3"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:如何设定我的 shell 提示??")])]),_._v(" "),v("p",[_._v("回答:如果你有足够的智慧提这个问题,你也该有足够的智慧去 "),v("a",{attrs:{href:"#RTFM"}},[_._v("RTFM")]),_._v(",然后自己去找出来。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q4"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文件转换为 TeX 格式吗?")])]),_._v(" "),v("p",[_._v("回答:试试看就知道了。如果你试过,你就知道了答案,就不用浪费我的时间了。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q5"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的{程序/设定/SQL 语句}没有用")])]),_._v(" "),v("p",[_._v("回答:这不算是问题吧,我对要我问你二十个问题才找得出你真正问题的问题没兴趣 —— 我有更有意思的事要做呢。在看到这类问题的时候,我的反应通常不外如下三种")]),_._v(" "),v("ul",[v("li",[_._v("你还有什么要补充的吗?")]),_._v(" "),v("li",[_._v("真糟糕,希望你能搞定。")]),_._v(" "),v("li",[_._v("这关我屁事?")])]),_._v(" "),v("p",[v("a",{attrs:{id:"q6"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的 Windows 电脑有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("回答:能啊,扔掉微软的垃圾,换个像 Linux 或 BSD 的开源操作系统吧。")]),_._v(" "),v("p",[_._v("注意:如果程序有官方版 Windows 或者与 Windows 有互动(如 Samba),你"),v("strong",[_._v("可以")]),_._v("问与 Windows 相关的问题,只是别对问题是由 Windows 操作系统而不是程序本身造成的回复感到惊讶, 因为 Windows 一般来说实在太烂,这种说法通常都是对的。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q7"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的程序不会动了,我认为系统工具 X 有问题")])]),_._v(" "),v("p",[_._v("回答:你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与函数库文件有明显缺陷的人,更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据,当你这样声称时,你必须有清楚而详尽的缺陷说明文件作后盾。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q8"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我在安装 Linux(或者 X )时有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("回答:不能,我只有亲自在你的电脑上动手才能找到毛病。还是去找你当地的 Linux 使用群组者寻求实际的指导吧(你能在"),v("a",{attrs:{href:"http://www.linux.org/groups/index.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("这儿"),v("OutboundLink")],1),_._v("找到用户群组的清单)。")]),_._v(" "),v("p",[_._v("注意:如果安装问题与某 Linux 的发行版有关,在它的邮件列表、论坛或本地用户群组中提问也许是恰当的。此时,应描述问题的准确细节。在此之前,先用 "),v("code",[_._v("Linux")]),_._v(" 和"),v("strong",[_._v("所有")]),_._v("被怀疑的硬件作关键词仔细搜索。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q9"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?")])]),_._v(" "),v("p",[_._v("回答:想要这样做,说明了你是个卑鄙小人;想找个黑客帮你,说明你是个白痴!")]),_._v(" "),v("h2",{attrs:{id:"好问题与蠢问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#好问题与蠢问题"}},[_._v("#")]),_._v(" 好问题与蠢问题")]),_._v(" "),v("p",[_._v("最后,我将透过举一些例子,来说明怎样聪明的提问;同一个问题的两种问法被放在一起,一种是愚蠢的,另一种才是明智的。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我可以在哪儿找到关于 Foonly Flurbamatic 的资料?")])]),_._v(" "),v("p",[_._v("这种问法无非想得到 "),v("a",{attrs:{href:"#RTFM"}},[_._v("STFW")]),_._v(" 这样的回答。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v('我用 Google 搜索过 "Foonly Flurbamatic 2600",但是没找到有用的结果。谁知道上哪儿去找对这种设备编程的资料?')])]),_._v(" "),v("p",[_._v("这个问题已经 STFW 过了,看起来他真的遇到了麻烦。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我从 foo 项目找来的源码没法编译。它怎么这么烂?")])]),_._v(" "),v("p",[_._v("他觉得都是别人的错,这个傲慢自大的提问者。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ,但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录,我有什么做的不对的地方吗?")])]),_._v(" "),v("p",[_._v("提问者已经指明了环境,也读过了 FAQ,还列出了错误,并且他没有把问题的责任推到别人头上,他的问题值得被关注。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我的主机板有问题了,谁来帮我?")])]),_._v(" "),v("p",[_._v("某黑客对这类问题的回答通常是:"),v("code",[_._v("好的,还要帮你拍拍背和换尿布吗?")]),_._v(",然后按下删除键。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我在 S2464 主机板上试过了 X 、 Y 和 Z ,但没什么作用,我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking,但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么?有谁知道接下来我该做些什么测试才能找出问题?")])]),_._v(" "),v("p",[_._v("这个家伙,从另一个角度来看,值得去回答他。他表现出了解决问题的能力,而不是坐等天上掉答案。")]),_._v(" "),v("p",[_._v("在最后一个问题中,注意"),v("code",[_._v("告诉我答案")]),_._v("和"),v("code",[_._v("给我启示,指出我还应该做什么诊断工作")]),_._v("之间微妙而又重要的区别。")]),_._v(" "),v("p",[_._v("事实上,后一个问题源自于 2001 年 8 月在 Linux 内核邮件列表(lkml)上的一个真实的提问。我(Eric)就是那个提出问题的人。我在 Tyan S2464 主板上观察到了这种无法解释的锁定现象,列表成员们提供了解决这一问题的重要信息。")]),_._v(" "),v("p",[_._v("通过我的提问方法,我给了别人可以咀嚼玩味的东西;我设法让人们很容易参与并且被吸引进来。我显示了自己具备和他们同等的能力,并邀请他们与我共同探讨。通过告诉他们我所走过的弯路,以避免他们再浪费时间,我也表明了对他们宝贵时间的尊重。")]),_._v(" "),v("p",[_._v("事后,当我向每个人表示感谢,并且赞赏这次良好的讨论经历的时候,一个 Linux 内核邮件列表的成员表示,他觉得我的问题得到解决并非由于我是这个列表中的"),v("strong",[_._v("名")]),_._v("人,而是因为我用了正确的方式来提问。")]),_._v(" "),v("p",[_._v("黑客从某种角度来说是拥有丰富知识但缺乏人情味的家伙;我相信他是对的,如果我"),v("strong",[_._v("像")]),_._v("个乞讨者那样提问,不论我是谁,一定会惹恼某些人或者被他们忽视。他建议我记下这件事,这直接导致了本指南的出现。")]),_._v(" "),v("h2",{attrs:{id:"如果得不到回答"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如果得不到回答"}},[_._v("#")]),_._v(" 如果得不到回答")]),_._v(" "),v("p",[_._v("如果仍得不到回答,请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。没有回应不代表你被忽视,虽然不可否认这种差别很难区分。")]),_._v(" "),v("p",[_._v("总的来说,简单地重复张贴问题是个很糟的点子。这将被视为无意义的喧闹。有点耐心,知道你问题答案的人可能生活在不同的时区,可能正在睡觉,也有可能你的问题一开始就没有组织好。")]),_._v(" "),v("p",[_._v("你可以通过其他渠道获得帮助,这些渠道通常更适合初学者的需要。")]),_._v(" "),v("p",[_._v("有许多网上的以及本地的用户群组,由热情的软件爱好者(即使他们可能从没亲自写过任何软件)组成。通常人们组建这样的团体来互相帮助并帮助新手。")]),_._v(" "),v("p",[_._v("另外,你可以向很多商业公司寻求帮助,不论公司大还是小。别为要付费才能获得帮助而感到沮丧!毕竟,假使你的汽车发动机汽缸密封圈爆掉了 —— 完全可能如此 —— 你还得把它送到修车铺,并且为维修付费。就算软件没花费你一分钱,你也不能强求技术支持总是免费的。")]),_._v(" "),v("p",[_._v("对像是 Linux 这种大众化的软件,每个开发者至少会对应到上万名用户。根本不可能由一个人来处理来自上万名用户的求助电话。要知道,即使你要为这些协助付费,和你所购买的同类软件相比,你所付出的也是微不足道的(通常封闭源代码软件的技术支持费用比开源软件的要高得多,且内容也没那么丰富)。")]),_._v(" "),v("h2",{attrs:{id:"如何更好地回答问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何更好地回答问题"}},[_._v("#")]),_._v(" 如何更好地回答问题")]),_._v(" "),v("p",[v("strong",[_._v("态度和善一点。")]),_._v(" 问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。")]),_._v(" "),v("p",[v("strong",[_._v("对初犯者私下回复。")]),_._v(" 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找常见问题都不知道。")]),_._v(" "),v("p",[v("strong",[_._v("如果你不确定,一定要说出来!")]),_._v(" 一个听起来权威的错误回复比没有还要糟,别因为听起来像个专家很好玩,就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。")]),_._v(" "),v("p",[v("strong",[_._v("如果帮不了忙,也别妨碍他。")]),_._v(" 不要在实际步骤上开玩笑,那样也许会毁了提问者的设置 —— 有些可怜的呆瓜会把它当成真的指令。")]),_._v(" "),v("p",[v("strong",[_._v("试探性的反问以引出更多的细节。")]),_._v(" 如果你做得好,提问者可以学到点东西 —— 你也可以。试试将蠢问题转变成好问题,别忘了我们都曾是新手。")]),_._v(" "),v("p",[_._v("尽管对那些懒虫抱怨一声 RTFM 是正当的,但能给出文档的链接(即使只是建议个 Google 搜索关键词)会更好。")]),_._v(" "),v("p",[v("strong",[_._v("如果你决定回答,就请给出好的答案。")]),_._v(" 当别人正在用错误的工具或方法时别建议笨拙的权宜之计(workaround),应推荐更好的工具,重新界定问题。")]),_._v(" "),v("p",[v("strong",[_._v("正面地回答问题!")]),_._v(" 如果这个提问者已经很深入的研究而且也表明已经试过 X 、 Y 、 Z 、 A 、 B 、 C 但没得到结果,回答 "),v("code",[_._v("试试看 A 或是 B")]),_._v(" 或者 "),v("code",[_._v("试试 X 、 Y 、 Z 、 A 、 B 、 C")]),_._v(" 并附上一个链接一点用都没有。")]),_._v(" "),v("p",[v("strong",[_._v("帮助你的社区从问题中学习。")]),_._v(" 当回复一个好问题时,问问自己"),v("code",[_._v("如何修改相关文件或常见问题文件以免再次解答同样的问题?")]),_._v(",接着再向文件维护者发一份补丁。")]),_._v(" "),v("p",[_._v("如果你在研究一番后才作出了回答,"),v("strong",[_._v("展现你的技巧而不是直接端出结果")]),_._v("。毕竟"),v("code",[_._v("授人以鱼不如授人以渔")]),_._v("。")]),_._v(" "),v("h2",{attrs:{id:"相关资源"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#相关资源"}},[_._v("#")]),_._v(" 相关资源")]),_._v(" "),v("p",[_._v("如果你需要个人电脑、Unix 系统和网络如何运作的基础知识,参阅 "),v("a",{attrs:{href:"http://en.tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Unix 系统和网络基本原理"),v("OutboundLink")],1),_._v("。")]),_._v(" "),v("p",[_._v("当你发布软件或补丁时,试着按"),v("a",{attrs:{href:"http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/index.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("软件发布实践"),v("OutboundLink")],1),_._v("操作。")]),_._v(" "),v("h2",{attrs:{id:"鸣谢"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#鸣谢"}},[_._v("#")]),_._v(" 鸣谢")]),_._v(" "),v("p",[_._v("Evelyn Mitchel 贡献了一些愚蠢问题例子并启发了编写"),v("code",[_._v("如何更好地回答问题")]),_._v("这一节, Mikhail Ramendik 贡献了一些特别有价值的建议和改进。")])])}),[],!1,null,null,null);v.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{321:function(_,v,t){"use strict";t.r(v);var r=t(14),e=Object(r.a)({},(function(){var _=this,v=_._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[v("p",[_._v("文档引用自:"),v("a",{attrs:{href:"https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way",target:"_blank",rel:"noopener noreferrer"}},[_._v("提问的智慧"),v("OutboundLink")],1)]),_._v(" "),v("h2",{attrs:{id:"在提问之前"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#在提问之前"}},[_._v("#")]),_._v(" 在提问之前")]),_._v(" "),v("p",[_._v("在你准备要通过电子邮件、新闻群组或者聊天室提出技术问题前,请先做到以下事情:")]),_._v(" "),v("ol",[v("li",[_._v("尝试在你准备提问的论坛的旧文章中搜索答案。")]),_._v(" "),v("li",[_._v("尝试上网搜索以找到答案。")]),_._v(" "),v("li",[_._v("尝试阅读手册以找到答案。")]),_._v(" "),v("li",[_._v("尝试阅读常见问题文件(FAQ)以找到答案。")]),_._v(" "),v("li",[_._v("尝试自己检查或试验以找到答案。")]),_._v(" "),v("li",[_._v("向你身边的强者朋友打听以找到答案。")]),_._v(" "),v("li",[_._v("如果你是程序开发者,请尝试阅读源代码以找到答案。")])]),_._v(" "),v("p",[_._v("当你提出问题的时候,请先表明你已经做了上述的努力;这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者。如果你能一并表达在做了上述努力的过程中所"),v("strong",[_._v("学到")]),_._v("的东西会更好,因为我们更乐于回答那些表现出能从答案中学习的人的问题。")]),_._v(" "),v("p",[_._v("运用某些策略,比如先用 Google 搜索你所遇到的各种错误信息(搜索 "),v("a",{attrs:{href:"http://groups.google.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google 论坛"),v("OutboundLink")],1),_._v("和网页),这样很可能直接就找到了能解决问题的文件或邮件列表线索。即使没有结果,在邮件列表或新闻组寻求帮助时加上一句 "),v("code",[_._v("我在 Google 中搜过下列句子但没有找到什么有用的东西")]),_._v(" 也是件好事,即使它只是表明了搜索引擎不能提供哪些帮助。这么做(加上搜索过的字串)也让遇到相似问题的其他人能被搜索引擎引导到你的提问来。")]),_._v(" "),v("p",[_._v("别着急,不要指望几秒钟的 Google 搜索就能解决一个复杂的问题。在向专家求助之前,再阅读一下常见问题文件(FAQ)、放轻松、坐得舒服一些,再花点时间思考一下这个问题。相信我们,他们能从你的提问看出你做了多少阅读与思考,如果你是有备而来,将更有可能得到解答。不要将所有问题一股脑拋出,只因你的第一次搜索没有找到答案(或者找到太多答案)。")]),_._v(" "),v("p",[_._v("准备好你的问题,再将问题仔细地思考过一遍,因为草率的发问只能得到草率的回答,或者根本得不到任何答案。越是能表现出在寻求帮助前你为解决问题所付出的努力,你越有可能得到实质性的帮助。")]),_._v(" "),v("p",[_._v("小心别问错了问题。如果你的问题基于错误的假设,某个普通黑客(J. Random Hacker)多半会一边在心里想着"),v("code",[_._v("蠢问题…")]),_._v(",一边用无意义的字面解释来答复你,希望着你会从问题的回答(而非你想得到的答案)中汲取教训。")]),_._v(" "),v("p",[_._v("绝不要自以为"),v("strong",[_._v("够格")]),_._v("得到答案,你没有;你并没有。毕竟你没有为这种服务支付任何报酬。你将会是自己去"),v("strong",[_._v("挣到")]),_._v("一个答案,靠提出有内涵的、有趣的、有思维激励作用的问题 —— 一个有潜力能贡献社区经验的问题,而不仅仅是被动地从他人处索取知识。")]),_._v(" "),v("p",[_._v("另一方面,表明你愿意在找答案的过程中做点什么是一个非常好的开端。"),v("code",[_._v("谁能给点提示?")]),_._v("、"),v("code",[_._v("我的这个例子里缺了什么?")]),_._v("以及"),v("code",[_._v("我应该检查什么地方")]),_._v("比"),v("code",[_._v("请把我需要的确切的过程贴出来")]),_._v("更容易得到答复。因为你表现出只要有人能指个正确方向,你就有完成它的能力和决心。")]),_._v(" "),v("h2",{attrs:{id:"当你提问时"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#当你提问时"}},[_._v("#")]),_._v(" 当你提问时")]),_._v(" "),v("h3",{attrs:{id:"慎选提问的论坛"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#慎选提问的论坛"}},[_._v("#")]),_._v(" 慎选提问的论坛")]),_._v(" "),v("p",[_._v("小心选择你要提问的场合。如果你做了下述的事情,你很可能被忽略掉或者被看作失败者:")]),_._v(" "),v("ul",[v("li",[_._v("在与主题不合的论坛上贴出你的问题。")]),_._v(" "),v("li",[_._v("在探讨进阶技术问题的论坛张贴非常初级的问题;反之亦然。")]),_._v(" "),v("li",[_._v("在太多的不同新闻群组上重复转贴同样的问题(cross-post)。")]),_._v(" "),v("li",[_._v("向既非熟人也没有义务解决你问题的人发送私人电邮。")])]),_._v(" "),v("p",[_._v("黑客会剔除掉那些搞错场合的问题,以保护他们沟通的渠道不被无关的东西淹没。你不会想让这种事发生在自己身上的。")]),_._v(" "),v("p",[_._v("因此,第一步是找到对的论坛。再说一次,Google 和其它搜索引擎还是你的朋友,用它们来找到与你遭遇到困难的软硬件问题最相关的网站。通常那儿都有常见问题(FAQ)、邮件列表及相关说明文件的链接。如果你的努力(包括"),v("strong",[_._v("阅读")]),_._v(" FAQ)都没有结果,网站上也许还有报告 Bug(Bug-reporting)的流程或链接,如果是这样,链过去看看。")]),_._v(" "),v("p",[_._v("向陌生的人或论坛发送邮件最可能是风险最大的事情。举例来说,别假设一个提供丰富内容的网页的作者会想充当你的免费顾问。不要对你的问题是否会受到欢迎做太乐观的估计 —— 如果你不确定,那就向别处发送,或者压根别发。")]),_._v(" "),v("p",[_._v("在选择论坛、新闻群组或邮件列表时,别太相信它的名字,先看看 FAQ 或者许可书以弄清楚你的问题是否切题。发文前先翻翻已有的话题,这样可以让你感受一下那里的文化。事实上,事先在新闻组或邮件列表的历史记录中搜索与你问题相关的关键词是个极好的主意,也许这样就找到答案了。即使没有,也能帮助你归纳出更好的问题。")]),_._v(" "),v("p",[_._v("别像机关枪似的一次“扫射”所有的帮助渠道,这就像大喊大叫一样会使人不快。要一个一个地来。")]),_._v(" "),v("p",[_._v("搞清楚你的主题!最典型的错误之一是在某种致力于跨平台可移植的语言、套件或工具的论坛中提关于 Unix 或 Windows 操作系统程序界面的问题。如果你不明白为什么这是大错,最好在搞清楚这之间差异之前什么也别问。")]),_._v(" "),v("p",[_._v("一般来说,在仔细挑选的公共论坛中提问,会比在私有论坛中提同样的问题更容易得到有用的回答。有几个理由可以支持这点,一是看潜在的回复者有多少,二是看观众有多少。黑客较愿意回答那些能帮助到许多人的问题。")]),_._v(" "),v("p",[_._v("可以理解的是,老练的黑客和一些热门软件的作者正在接受过多的错发信息。就像那根最后压垮骆驼背的稻草一样,你的加入也有可能使情况走向极端 —— 已经好几次了,一些热门软件的作者由于涌入其私人邮箱的大量不堪忍受的无用邮件而不再提供支持。")]),_._v(" "),v("h3",{attrs:{id:"stack-overflow"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#stack-overflow"}},[_._v("#")]),_._v(" Stack Overflow")]),_._v(" "),v("p",[_._v("搜索,"),v("em",[_._v("然后")]),_._v("在 Stack Exchange 问。")]),_._v(" "),v("p",[_._v("近年来,Stack Exchange 社区已经成为回答技术及其他问题的主要渠道,尤其是那些开放源码的项目。")]),_._v(" "),v("p",[_._v("因为 Google 索引是即时的,在看 Stack Exchange 之前先在 Google 搜索。有很高的几率某人已经问了一个类似的问题,而且 Stack Exchange 网站们往往会是搜索结果中最前面几个。如果你在 Google 上没有找到任何答案,你再到特定相关主题的网站去找。用标签(Tag)搜索能让你更缩小你的搜索结果。")]),_._v(" "),v("p",[_._v("如果你还是找不到任何对你的问题有用的内容,请把你的问题发在与它最相关的网站上。提问的时候请善用格式化工具,尤其注意为代码添加格式,并且添加相关的标签(特别是编程语言、操作系统或库/包的名称)。当有人要求你提供更多相关信息时,请编辑你的贴子来补充它们[译注:而不是发一个回帖或回答!]。如果你觉得一个答案对你有帮助,点击向上的箭头来为它投票;如果一个答案提供了问题的正确解决方案,点击投票按钮下方的对勾来将它标记为正解。")]),_._v(" "),v("p",[_._v("Stack Exchange 已经成长到"),v("a",{attrs:{href:"https://stackexchange.com/sites",target:"_blank",rel:"noopener noreferrer"}},[_._v("超过一百个网站"),v("OutboundLink")],1),_._v(",以下是最常用的几个站:")]),_._v(" "),v("ul",[v("li",[_._v("Super User 是问一些通用的电脑问题,如果你的问题跟代码或是写程序无关,只是一些网络连线之类的,请到这里。")]),_._v(" "),v("li",[_._v("Stack Overflow 是问写程序有关的问题。")]),_._v(" "),v("li",[_._v("Server Fault 是问服务器和网管相关的问题。")])]),_._v(" "),v("h3",{attrs:{id:"网站和-irc-论坛"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#网站和-irc-论坛"}},[_._v("#")]),_._v(" 网站和 IRC 论坛")]),_._v(" "),v("p",[_._v("本地的用户群组(user group),或者你所用的 Linux 发行版本也许正在宣传他们的网页论坛或 IRC 频道,并提供新手帮助(在一些非英语国家,新手论坛很可能还是邮件列表),这些都是开始提问的好地方,特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。有广告赞助的 IRC 频道是公开欢迎提问的地方,通常可以即时得到回应。")]),_._v(" "),v("p",[_._v("事实上,如果程序出的问题只发生在特定 Linux 发行版提供的版本(这很常见),最好先去该发行版的论坛或邮件列表中提问,再到程序本身的论坛或邮件列表提问。(否则)该项目的黑客可能仅仅回复“使用"),v("strong",[_._v("我们的")]),_._v("版本”。")]),_._v(" "),v("p",[_._v("在任何论坛发文以前,先确认一下有没有搜索功能。如果有,就试着搜索一下问题的几个关键词,也许这会有帮助。如果在此之前你已做过通用的网页搜索(你也该这样做),还是再搜索一下论坛,搜索引擎有可能没来得及索引此论坛的全部内容。")]),_._v(" "),v("p",[_._v("通过论坛或 IRC 频道来提供用户支持服务有增长的趋势,电子邮件则大多为项目开发者间的交流而保留。所以最好先在论坛或 IRC 中寻求与该项目相关的协助。")]),_._v(" "),v("p",[_._v("在使用 IRC 的时候,首先最好不要发布很长的问题描述,有些人称之为频道洪水。最好通过一句话的问题描述来开始聊天。")]),_._v(" "),v("h3",{attrs:{id:"第二步-使用项目邮件列表"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#第二步-使用项目邮件列表"}},[_._v("#")]),_._v(" 第二步,使用项目邮件列表")]),_._v(" "),v("p",[_._v("当某个项目提供开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。查一查项目的文件和首页,找到项目的邮件列表并使用它。有几个很好的理由支持我们采用这种办法:")]),_._v(" "),v("ul",[v("li",[_._v("任何好到需要向个别开发者提出的问题,也将对整个项目群组有益。反之,如果你认为自己的问题对整个项目群组来说太愚蠢,那这也不能成为骚扰个别开发者的理由。")]),_._v(" "),v("li",[_._v("向列表提问可以分散开发者的负担,个别开发者(尤其是项目领导人)也许太忙以至于没法回答你的问题。")]),_._v(" "),v("li",[_._v("大多数邮件列表都会被存档,那些被存档的内容将被搜索引擎索引。如果你向列表提问并得到解答,将来其他人可以通过网页搜索找到你的问题和答案,也就不用再次发问了。")]),_._v(" "),v("li",[_._v("如果某些问题经常被问到,开发者可以利用此信息来改进说明文件或软件本身,以使其更清楚。如果只是私下提问,就没有人能看到最常见问题的完整场景。")])]),_._v(" "),v("p",[_._v("如果一个项目既有“用户”也有“开发者”(或“黑客”)邮件列表或论坛,而你又不会动到那些源代码,那么就向“用户”列表或论坛提问。不要假设自己会在开发者列表中受到欢迎,那些人多半会将你的提问视为干扰他们开发的噪音。")]),_._v(" "),v("p",[_._v("然而,如果你"),v("strong",[_._v("确信")]),_._v("你的问题很特别,而且在“用户”列表或论坛中几天都没有回复,可以试试前往“开发者”列表或论坛发问。建议你在张贴前最好先暗地里观察几天以了解那里的行事方式(事实上这是参与任何私有或半私有列表的好主意)")]),_._v(" "),v("p",[_._v("如果你找不到一个项目的邮件列表,而只能查到项目维护者的电子邮件地址,尽管向他发信。即使是在这种情况下,也别假设(项目)邮件列表不存在。在你的电子邮件中,请陈述你已经试过但没有找到合适的邮件列表,也提及你不反对将自己的邮件转发给他人(许多人认为,即使没什么秘密,私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人,你给了相应人员处置你邮件的选择)。")]),_._v(" "),v("h3",{attrs:{id:"使用有意义且描述明确的标题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用有意义且描述明确的标题"}},[_._v("#")]),_._v(" 使用有意义且描述明确的标题")]),_._v(" "),v("p",[_._v("在邮件列表、新闻群组或论坛中,大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的"),v("code",[_._v("帮帮忙")]),_._v("、"),v("code",[_._v("跪求")]),_._v("、"),v("code",[_._v("急")]),_._v("(更别说"),v("code",[_._v("救命啊!!!!")]),_._v("这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动我们,而应该是在这点空间中使用极简单扼要的描述方式来提出问题。")]),_._v(" "),v("p",[_._v("一个好标题范例是"),v("code",[_._v("目标 —— 差异")]),_._v("式的描述,许多技术支持组织就是这样做的。在"),v("code",[_._v("目标")]),_._v("部分指出是哪一个或哪一组东西有问题,在"),v("code",[_._v("差异")]),_._v("部分则描述与期望的行为不一致的地方。")]),_._v(" "),v("blockquote",[v("p",[_._v("蠢问题:救命啊!我的笔记本电脑不能正常显示了!")])]),_._v(" "),v("blockquote",[v("p",[_._v("聪明问题:X.org 6.8.1 的鼠标指针会变形,某牌显卡 MV1005 芯片组。")])]),_._v(" "),v("blockquote",[v("p",[_._v("更聪明问题:X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。")])]),_._v(" "),v("p",[_._v("编写"),v("code",[_._v("目标 —— 差异")]),_._v(" 式描述的过程有助于你组织对问题的细致思考。是什么被影响了? 仅仅是鼠标指针或者还有其它图形?只在 X.org 的 X 版中出现?或只是出现在 6.8.1 版中? 是针对某牌显卡芯片组?或者只是其中的 MV1005 型号? 一个黑客只需瞄一眼就能够立即明白你的环境"),v("strong",[_._v("和")]),_._v("你遇到的问题。")]),_._v(" "),v("p",[_._v("总而言之,请想像一下你正在一个只显示标题的存档讨论串(Thread)索引中查寻。让你的标题更好地反映问题,可使下一个搜索类似问题的人能够关注这个讨论串,而不用再次提问相同的问题。")]),_._v(" "),v("p",[_._v("如果你想在回复中提出问题,记得要修改内容标题,以表明你是在问一个问题, 一个看起来像 "),v("code",[_._v("Re: 测试")]),_._v(" 或者 "),v("code",[_._v("Re: 新 bug")]),_._v(" 的标题很难引起足够重视。另外,在不影响连贯性之下,适当引用并删减前文的内容,能给新来的读者留下线索。")]),_._v(" "),v("p",[_._v("对于讨论串,不要直接点击回复来开始一个全新的讨论串,这将限制你的观众。因为有些邮件阅读程序,比如 mutt ,允许用户按讨论串排序并通过折叠讨论串来隐藏消息,这样做的人永远看不到你发的消息。")]),_._v(" "),v("p",[_._v("仅仅改变标题还不够。mutt 和其它一些邮件阅读程序还会检查邮件标题以外的其它信息,以便为其指定讨论串。所以宁可发一个全新的邮件。")]),_._v(" "),v("p",[_._v("在网页论坛上,好的提问方式稍有不同,因为讨论串与特定的信息紧密结合,并且通常在讨论串外就看不到里面的内容,故通过回复提问,而非改变标题是可接受的。不是所有论坛都允许在回复中出现分离的标题,而且这样做了基本上没有人会去看。不过,通过回复提问,这本身就是暧昧的做法,因为它们只会被正在查看该标题的人读到。所以,除非你"),v("strong",[_._v("只想")]),_._v("在该讨论串当前活跃的人群中提问,不然还是另起炉灶比较好。")]),_._v(" "),v("h3",{attrs:{id:"使问题容易回复"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使问题容易回复"}},[_._v("#")]),_._v(" 使问题容易回复")]),_._v(" "),v("p",[_._v("以"),v("code",[_._v("请将你的回复发送到……")]),_._v("来结束你的问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦,我们也觉得花几秒钟思考你的问题更麻烦。如果你的邮件程序不支持这样做,"),v("a",{attrs:{href:"http://linuxmafia.com/faq/Mail/muas.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("换个好点的"),v("OutboundLink")],1),_._v(";如果是操作系统不支持这种邮件程序,也换个好点的。")]),_._v(" "),v("p",[_._v("在论坛,要求通过电子邮件回复是非常无礼的,除非你认为回复的信息可能比较敏感(有人会为了某些未知的原因,只让你而不是整个论坛知道答案)。如果你只是想在有人回复讨论串时得到电子邮件提醒,可以要求网页论坛发送给你。几乎所有论坛都支持诸如"),v("code",[_._v("追踪此讨论串")]),_._v("、"),v("code",[_._v("有回复时发送邮件提醒")]),_._v("等功能。")]),_._v(" "),v("h3",{attrs:{id:"使用清晰、正确、精准且合乎语法的语句"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用清晰、正确、精准且合乎语法的语句"}},[_._v("#")]),_._v(" "),v("a",{attrs:{name:"使用清晰、正确、精准且合乎语法的语句"}},[_._v("使用清晰、正确、精准且合乎语法的语句")])]),_._v(" "),v("p",[_._v("我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。")]),_._v(" "),v("p",[_._v("正确的拼写、标点符号和大小写是很重要的。一般来说,如果你觉得这样做很麻烦,不想在乎这些,那我们也觉得麻烦,不想在乎你的提问。花点额外的精力斟酌一下字句,用不着太僵硬与正式 —— 事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它"),v("strong",[_._v("必须很")]),_._v("准确,而且有迹象表明你是在思考和关注问题。")]),_._v(" "),v("p",[_._v("正确地拼写、使用标点和大小写,不要将"),v("code",[_._v("its")]),_._v("混淆为"),v("code",[_._v("it's")]),_._v(","),v("code",[_._v("loose")]),_._v("搞成"),v("code",[_._v("lose")]),_._v("或者将"),v("code",[_._v("discrete")]),_._v("弄成"),v("code",[_._v("discreet")]),_._v("。不要"),v("strong",[_._v("全部用大写")]),_._v(",这会被视为无礼的大声嚷嚷(全部小写也好不到哪去,因为不易阅读。"),v("a",{attrs:{href:"http://en.wikipedia.org/wiki/Alan_Cox",target:"_blank",rel:"noopener noreferrer"}},[_._v("Alan Cox"),v("OutboundLink")],1),_._v(" 也许可以这样做,但你不行)。")]),_._v(" "),v("p",[_._v("更白话的说,如果你写得像是个半文盲[译注:"),v("a",{attrs:{href:"http://zh.wikipedia.org/wiki/%E5%B0%8F%E7%99%BD",target:"_blank",rel:"noopener noreferrer"}},[_._v("小白"),v("OutboundLink")],1),_._v("],那多半得不到理睬。也不要使用即时通信中的简写或"),v("a",{attrs:{href:"http://zh.wikipedia.org/wiki/%E7%81%AB%E6%98%9F%E6%96%87",target:"_blank",rel:"noopener noreferrer"}},[_._v("火星文"),v("OutboundLink")],1),_._v(",如将"),v("code",[_._v("的")]),_._v("简化为"),v("code",[_._v("d")]),_._v("会使你看起来像一个为了少打几个键而省字的小白。更糟的是,如果像个小孩似地鬼画符那绝对是在找死,可以肯定没人会理你(或者最多是给你一大堆指责与挖苦)。")]),_._v(" "),v("p",[_._v("如果在使用非母语的论坛提问,你可以犯点拼写和语法上的小错,但决不能在思考上马虎(没错,我们通常能弄清两者的分别)。同时,除非你知道回复者使用的语言,否则请使用英语书写。繁忙的黑客一般会直接删除用他们看不懂的语言写的消息。在网络上英语是通用语言,用英语书写可以将你的问题在尚未被阅读就被直接删除的可能性降到最低。")]),_._v(" "),v("p",[_._v("如果英文是你的外语(Second language),提示潜在回复者你有潜在的语言困难是很好的:\n[译注:以下附上原文以供使用]")]),_._v(" "),v("blockquote",[v("p",[_._v("English is not my native language; please excuse typing errors.")])]),_._v(" "),v("ul",[v("li",[_._v("英文不是我的母语,请原谅我的错字或语法。")])]),_._v(" "),v("blockquote",[v("p",[_._v("If you speak $LANGUAGE, please email/PM me;\nI may need assistance translating my question.")])]),_._v(" "),v("ul",[v("li",[_._v("如果你说"),v("strong",[_._v("某语言")]),_._v(",请向我发电邮/私信;")]),_._v(" "),v("li",[_._v("我需要有人协助我翻译我的问题。")])]),_._v(" "),v("blockquote",[v("p",[_._v("I am familiar with the technical terms,\nbut some slang expressions and idioms are difficult for me.")])]),_._v(" "),v("ul",[v("li",[_._v("我对技术名词很熟悉,但对于俗语或是特别用法不甚了解。")])]),_._v(" "),v("blockquote",[v("p",[_._v("I've posted my question in $LANGUAGE and English.\nI'll be glad to translate responses, if you only use one or the other.")])]),_._v(" "),v("ul",[v("li",[_._v("我把我的问题用"),v("strong",[_._v("某语言")]),_._v("和英文写出来。")]),_._v(" "),v("li",[_._v("如果你只用其中的一种语言回答,我会乐意将回复翻译成为你使用的语言。")])]),_._v(" "),v("h3",{attrs:{id:"使用易于读取且标准的文件格式发送问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#使用易于读取且标准的文件格式发送问题"}},[_._v("#")]),_._v(" 使用易于读取且标准的文件格式发送问题")]),_._v(" "),v("p",[_._v("如果你人为地将问题搞得难以阅读,它多半会被忽略,人们更愿读易懂的问题,所以:")]),_._v(" "),v("ul",[v("li",[_._v("使用纯文字而不是 HTML ("),v("a",{attrs:{href:"http://archive.birdhouse.org/etc/evilmail.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("关闭 HTML"),v("OutboundLink")],1),_._v(" 并不难)。")]),_._v(" "),v("li",[_._v("使用 MIME 附件通常是可以的,前提是真正有内容(譬如附带的源代码或 patch),而不仅仅是邮件程序生成的模板(譬如只是信件内容的拷贝)。")]),_._v(" "),v("li",[_._v("不要发送一段文字只是一行句子但自动换行后会变成多行的邮件(这使得回复部分内容非常困难)。设想你的读者是在 80 个字符宽的终端机上阅读邮件,最好设置你的换行分割点小于 80 字。")]),_._v(" "),v("li",[_._v("但是,对一些特殊的文件"),v("strong",[_._v("不要")]),_._v("设置固定宽度(譬如日志文件拷贝或会话记录)。数据应该原样包含,让回复者有信心他们看到的是和你看到的一样的东西。")]),_._v(" "),v("li",[_._v("在英语论坛中,不要使用"),v("code",[_._v("Quoted-Printable")]),_._v(" MIME 编码发送消息。这种编码对于张贴非 ASCII 语言可能是必须的,但很多邮件程序并不支持这种编码。当它们处理换行时,那些文本中四处散布的"),v("code",[_._v("=20")]),_._v("符号既难看也分散注意力,甚至有可能破坏内容的语意。")]),_._v(" "),v("li",[_._v("绝对,"),v("strong",[_._v("永远")]),_._v("不要指望黑客们阅读使用封闭格式编写的文档,像微软公司的 Word 或 Excel 文件等。大多数黑客对此的反应就像有人将还在冒热气的猪粪倒在你家门口时你的反应一样。即便他们能够处理,他们也很厌恶这么做。")]),_._v(" "),v("li",[_._v("如果你从使用 Windows 的电脑发送电子邮件,关闭微软愚蠢的"),v("code",[_._v("智能引号")]),_._v("功能 (从[选项] > [校订] > [自动校正选项],勾选掉"),v("code",[_._v("智能引号")]),_._v("单选框),以免在你的邮件中到处散布垃圾字符。")]),_._v(" "),v("li",[_._v("在论坛,勿滥用"),v("code",[_._v("表情符号")]),_._v("和"),v("code",[_._v("HTML")]),_._v("功能(当它们提供时)。一两个表情符号通常没有问题,但花哨的彩色文本倾向于使人认为你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来像个傻笑的小姑娘。这通常不是个好主意,除非你只是对性而不是对答案感兴趣。")])]),_._v(" "),v("p",[_._v("如果你使用图形用户界面的邮件程序(如微软公司的 Outlook 或者其它类似的),注意它们的默认设置不一定满足这些要求。大多数这类程序有基于选单的"),v("code",[_._v("查看源代码")]),_._v("命令,用它来检查发送文件夹中的邮件,以确保发送的是纯文本文件同时没有一些奇怪的字符。")]),_._v(" "),v("h3",{attrs:{id:"精确地描述问题并言之有物"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#精确地描述问题并言之有物"}},[_._v("#")]),_._v(" 精确地描述问题并言之有物")]),_._v(" "),v("ul",[v("li",[_._v("仔细、清楚地描述你的问题或 Bug 的症状。")]),_._v(" "),v("li",[_._v("描述问题发生的环境(机器配置、操作系统、应用程序、以及相关的信息),提供经销商的发行版和版本号(如:"),v("code",[_._v("Fedora Core 4")]),_._v("、"),v("code",[_._v("Slackware 9.1")]),_._v("等)。")]),_._v(" "),v("li",[_._v("描述在提问前你是怎样去研究和理解这个问题的。")]),_._v(" "),v("li",[_._v("描述在提问前为确定问题而采取的诊断步骤。")]),_._v(" "),v("li",[_._v("描述最近做过什么可能相关的硬件或软件变更。")]),_._v(" "),v("li",[_._v("尽可能地提供一个可以"),v("code",[_._v("重现这个问题的可控环境")]),_._v("的方法。")])]),_._v(" "),v("p",[_._v("尽量去揣测一个黑客会怎样反问你,在你提问之前预先将黑客们可能提出的问题回答一遍。")]),_._v(" "),v("p",[_._v("以上几点中,当你报告的是你认为可能在代码中的问题时,给黑客一个可以重现你的问题的环境尤其重要。当你这么做时,你得到有效的回答的机会和速度都会大大的提升。")]),_._v(" "),v("p",[v("a",{attrs:{href:"http://www.chiark.greenend.org.uk/~sgtatham/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Simon Tatham"),v("OutboundLink")],1),_._v(" 写过一篇名为《"),v("a",{attrs:{href:"http://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("如何有效的报告 Bug"),v("OutboundLink")],1),_._v("》的出色文章。强力推荐你也读一读。")]),_._v(" "),v("h3",{attrs:{id:"话不在多而在精"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#话不在多而在精"}},[_._v("#")]),_._v(" 话不在多而在精")]),_._v(" "),v("p",[_._v("你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全转录到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境,尽量将它剪裁得越小越好。")]),_._v(" "),v("p",[_._v("这样做的用处至少有三点。\n第一,表现出你为简化问题付出了努力,这可以使你得到回答的机会增加;\n第二,简化问题使你更有可能得到"),v("strong",[_._v("有用")]),_._v("的答案;\n第三,在精炼你的 bug 报告的过程中,你很可能就自己找到了解决方法或权宜之计。")]),_._v(" "),v("h3",{attrs:{id:"别动辄声称找到-bug"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别动辄声称找到-bug"}},[_._v("#")]),_._v(" 别动辄声称找到 Bug")]),_._v(" "),v("p",[_._v("当你在使用软件中遇到问题,除非你非常、"),v("strong",[_._v("非常")]),_._v("的有根据,不要动辄声称找到了 Bug。提示:除非你能提供解决问题的源代码补丁,或者提供回归测试来表明前一版本中行为不正确,否则你都多半不够完全确信。这同样适用在网页和文件,如果你(声称)发现了文件的"),v("code",[_._v("Bug")]),_._v(",你应该能提供相应位置的修正或替代文件。")]),_._v(" "),v("p",[_._v("请记得,还有其他许多用户没遇到你发现的问题,否则你在阅读文件或搜索网页时就应该发现了(你在抱怨前"),v("a",{attrs:{href:"#%E5%9C%A8%E6%8F%90%E9%97%AE%E4%B9%8B%E5%89%8D"}},[_._v("已经做了这些,是吧")]),_._v("?)。这也意味着很有可能是你弄错了而不是软件本身有问题。")]),_._v(" "),v("p",[_._v("编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了 Bug,也就是在质疑他们的能力,即使你是对的,也有可能会冒犯到其中某部分人。当你在标题中嚷嚷着有"),v("code",[_._v("Bug")]),_._v("时,这尤其严重。")]),_._v(" "),v("p",[_._v("提问时,即使你私下非常确信已经发现一个真正的 Bug,最好写得像是"),v("strong",[_._v("你")]),_._v("做错了什么。如果真的有 Bug,你会在回复中看到这点。这样做的话,如果真有 Bug,维护者就会向你道歉,这总比你惹恼别人然后欠别人一个道歉要好一点。")]),_._v(" "),v("h3",{attrs:{id:"低声下气不能代替你的功课"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#低声下气不能代替你的功课"}},[_._v("#")]),_._v(" 低声下气不能代替你的功课")]),_._v(" "),v("p",[_._v("有些人明白他们不该粗鲁或傲慢的提问并要求得到答复,但他们选择另一个极端 —— 低声下气:"),v("code",[_._v("我知道我只是个可悲的新手,一个撸瑟,但...")]),_._v("。这既使人困扰,也没有用,尤其是伴随着与实际问题含糊不清的描述时更令人反感。")]),_._v(" "),v("p",[_._v("别用原始灵长类动物的把戏来浪费你我的时间。取而代之的是,尽可能清楚地描述背景条件和你的问题情况。这比低声下气更好地定位了你的位置。")]),_._v(" "),v("p",[_._v("有时网页论坛会设有专为新手提问的版面,如果你真的认为遇到了初学者的问题,到那去就是了,但一样别那么低声下气。")]),_._v(" "),v("h3",{attrs:{id:"描述问题症状而非你的猜测"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#描述问题症状而非你的猜测"}},[_._v("#")]),_._v(" 描述问题症状而非你的猜测")]),_._v(" "),v("p",[_._v("告诉黑客们你认为问题是怎样造成的并没什么帮助。(如果你的推断如此有效,还用向别人求助吗?),因此要确信你原原本本告诉了他们问题的症状,而不是你的解释和理论;让黑客们来推测和诊断。如果你认为陈述自己的猜测很重要,清楚地说明这只是你的猜测,并描述为什么它们不起作用。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我在编译内核时接连遇到 SIG11 错误,\n我怀疑某条飞线搭在主板的走线上了,这种情况应该怎样检查最好?")])]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU(威盛 Apollo VP2 芯片组),\n256MB Corsair PC133 SDRAM 内存,在编译内核时,从开机 20 分钟以后就频频产生 SIG11 错误,\n但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用,但是关机一晚上就又能工作 20 分钟。\n所有内存都换过了,没有效果。相关部分的标准编译记录如下…")])]),_._v(" "),v("p",[_._v("由于以上这点似乎让许多人觉得难以配合,这里有句话可以提醒你:"),v("code",[_._v("所有的诊断专家都来自密苏里州。")]),_._v(" 美国国务院的官方座右铭则是:"),v("code",[_._v("让我看看")]),_._v("(出自国会议员 Willard D. Vandiver 在 1899 年时的讲话:"),v("code",[_._v("我来自一个出产玉米,棉花,牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。")]),_._v(") 针对诊断者而言,这并不是一种怀疑,而只是一种真实而有用的需求,以便让他们看到的是与你看到的原始证据尽可能一致的东西,而不是你的猜测与归纳的结论。所以,大方地展示给我们看吧!")]),_._v(" "),v("h3",{attrs:{id:"按发生时间先后列出问题症状"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#按发生时间先后列出问题症状"}},[_._v("#")]),_._v(" 按发生时间先后列出问题症状")]),_._v(" "),v("p",[_._v("问题发生前的一系列操作,往往就是对找出问题最有帮助的线索。因此,你的说明里应该包含你的操作步骤,以及机器和软件的反应,直到问题发生。在命令行处理的情况下,提供一段操作记录(例如运行脚本工具所生成的),并引用相关的若干行(如 20 行)记录会非常有帮助。")]),_._v(" "),v("p",[_._v("如果挂掉的程序有诊断选项(如 -v 的详述开关),试着选择这些能在记录中增加调试信息的选项。记住,"),v("code",[_._v("多")]),_._v("不等于"),v("code",[_._v("好")]),_._v("。试着选取适当的调试级别以便提供有用的信息而不是让读者淹没在垃圾中。")]),_._v(" "),v("p",[_._v("如果你的说明很长(如超过四个段落),在开头简述问题,接下来再按时间顺序详述会有所帮助。这样黑客们在读你的记录时就知道该注意哪些内容了。")]),_._v(" "),v("h3",{attrs:{id:"描述目标而不是过程"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#描述目标而不是过程"}},[_._v("#")]),_._v(" 描述目标而不是过程")]),_._v(" "),v("p",[_._v("如果你想弄清楚如何做某事(而不是报告一个 Bug),在开头就描述你的目标,然后才陈述重现你所卡住的特定步骤。")]),_._v(" "),v("p",[_._v("经常寻求技术帮助的人在心中有个更高层次的目标,而他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我怎样才能从某绘图程序的颜色选择器中取得十六进制的 RGB 值?")])]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")])]),_._v(" "),v("blockquote",[v("p",[_._v("我正试着用替换一幅图片的色码(color table)成自己选定的色码,我现在知道的唯一方法是编辑每个色码区块(table slot),\n但却无法从某绘图程序的颜色选择器取得十六进制的 RGB 值。")])]),_._v(" "),v("p",[_._v("第二种提问法比较聪明,你可能得到像是"),v("code",[_._v("建议采用另一个更合适的工具")]),_._v("的回复。")]),_._v(" "),v("h3",{attrs:{id:"别要求使用私人电邮回复"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别要求使用私人电邮回复"}},[_._v("#")]),_._v(" 别要求使用私人电邮回复")]),_._v(" "),v("p",[_._v("黑客们认为问题的解决过程应该公开、透明,此过程中如果更有经验的人注意到不完整或者不当之处,最初的回复才能够、也应该被纠正。同时,作为提供帮助者可以得到一些奖励,奖励就是他的能力和学识被其他同行看到。")]),_._v(" "),v("p",[_._v("当你要求私下回复时,这个过程和奖励都被中止。别这样做,让"),v("strong",[_._v("回复者")]),_._v("来决定是否私下回答 —— 如果他真这么做了,通常是因为他认为问题编写太差或者太肤浅,以至于不可能使其他人产生兴趣。")]),_._v(" "),v("p",[_._v("这条规则存在一条有限的例外,如果你确信提问可能会引来大量雷同的回复时,那么这个神奇的提问句会是"),v("code",[_._v("向我发电邮,我将为论坛归纳这些回复")]),_._v("。试着将邮件列表或新闻群组从洪水般的雷同回复中解救出来是非常有礼貌的 —— 但你必须信守诺言。")]),_._v(" "),v("h3",{attrs:{id:"清楚明确地表达你的问题以及需求"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#清楚明确地表达你的问题以及需求"}},[_._v("#")]),_._v(" 清楚明确地表达你的问题以及需求")]),_._v(" "),v("p",[_._v("漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人(他们忙是因为要亲自完成大部分工作)。这样的人对无节制的时间黑洞相当厌恶,所以他们也倾向于厌恶那些漫无边际的提问。")]),_._v(" "),v("p",[_._v("如果你明确表述需要回答者做什么(如提供指点、发送一段代码、检查你的补丁、或是其他等等),就最有可能得到有用的答案。因为这会定出一个时间和精力的上限,便于回答者能集中精力来帮你。这么做很棒。")]),_._v(" "),v("p",[_._v("要理解专家们所处的世界,请把专业技能想像为充裕的资源,而回复的时间则是稀缺的资源。你要求他们奉献的时间越少,你越有可能从真正专业而且很忙的专家那里得到解答。")]),_._v(" "),v("p",[_._v("所以,界定一下你的问题,使专家花在辨识你的问题和回答所需要付出的时间减到最少,这技巧对你获得有用的答案相当有帮助 —— 但这技巧通常和简化问题有所区别。因此,问"),v("code",[_._v("我想更好地理解 X,可否指点一下哪有好一点说明?")]),_._v("通常比问"),v("code",[_._v("你能解释一下 X 吗?")]),_._v("更好。如果你的代码不能运作,通常请别人看看哪里有问题,比要求别人替你改正要明智得多。")]),_._v(" "),v("h3",{attrs:{id:"询问有关代码的问题时"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#询问有关代码的问题时"}},[_._v("#")]),_._v(" 询问有关代码的问题时")]),_._v(" "),v("p",[_._v("如果没有提示别人应该从何入手,别要求他人帮你调试有问题的代码。张贴几百行的代码,然后说一声:"),v("code",[_._v("它不能工作")]),_._v("会让你完全被忽略。只贴几十行代码,然后说一句:"),v("code",[_._v("在第七行以后,我期待它显示 ,但实际出现的是 ")]),_._v("比较有可能让你得到回应。")]),_._v(" "),v("p",[_._v("最有效描述程序问题的方法是提供最精简的 Bug 展示测试用例(bug-demonstrating test case)。什么是最精简的测试用例?那是问题的缩影;一小个程序片段能"),v("strong",[_._v("刚好")]),_._v("展示出程序的异常行为,而不包含其他令人分散注意力的内容。怎么制作最精简的测试用例?如果你知道哪一行或哪一段代码会造成异常的行为,复制下来并加入足够重现这个状况的代码(例如,足以让这段代码能被编译/直译/被应用程序处理)。如果你无法将问题缩减到一个特定区块,就复制一份代码并移除不影响产生问题行为的部分。总之,测试用例越小越好(查看"),v("a",{attrs:{href:"#%E8%AF%9D%E4%B8%8D%E5%9C%A8%E5%A4%9A%E8%80%8C%E5%9C%A8%E7%B2%BE"}},[_._v("话不在多而在精")]),_._v("一节)。")]),_._v(" "),v("p",[_._v("一般而言,要得到一段相当精简的测试用例并不太容易,但永远先尝试这样做是一个好习惯。这种方式可以帮助你了解如何自行解决这个问题 —— 而且即使你的尝试不成功,黑客们也会看到你在尝试取得答案的过程中付出了努力,这可以让他们更愿意与你合作。")]),_._v(" "),v("p",[_._v("如果你只是想让别人帮忙审查(Review)一下代码,在信的开头就要说出来,并且一定要提到你认为哪一部分特别需要关注以及为什么。")]),_._v(" "),v("h3",{attrs:{id:"别把自己家庭作业的问题贴上来"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#别把自己家庭作业的问题贴上来"}},[_._v("#")]),_._v(" 别把自己家庭作业的问题贴上来")]),_._v(" "),v("p",[_._v("黑客们很擅长分辨哪些问题是家庭作业式的问题;因为我们中的大多数都曾自己解决这类问题。同样,这些问题得由"),v("strong",[_._v("你")]),_._v("来搞定,你会从中学到东西。你可以要求给点提示,但别要求得到完整的解决方案。")]),_._v(" "),v("p",[_._v("如果你怀疑自己碰到了一个家庭作业式的问题,但仍然无法解决,试试在用户群组,论坛或(最后一招)在项目的"),v("strong",[_._v("用户")]),_._v("邮件列表或论坛中提问。尽管黑客们"),v("strong",[_._v("会")]),_._v("看出来,但一些有经验的用户也许仍会给你一些提示。")]),_._v(" "),v("h3",{attrs:{id:"去掉无意义的提问句"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#去掉无意义的提问句"}},[_._v("#")]),_._v(" 去掉无意义的提问句")]),_._v(" "),v("p",[_._v("避免用无意义的话结束提问,例如"),v("code",[_._v("有人能帮我吗?")]),_._v("或者"),v("code",[_._v("这有答案吗?")]),_._v("。")]),_._v(" "),v("p",[_._v("首先:如果你对问题的描述不是很好,这样问更是画蛇添足。")]),_._v(" "),v("p",[_._v("其次:由于这样问是画蛇添足,黑客们会很厌烦你 —— 而且通常会用逻辑上正确,但毫无意义的回答来表示他们的蔑视, 例如:"),v("code",[_._v("没错,有人能帮你")]),_._v("或者"),v("code",[_._v("不,没答案")]),_._v("。")]),_._v(" "),v("p",[_._v("一般来说,避免用 "),v("code",[_._v("是或否")]),_._v("、"),v("code",[_._v("对或错")]),_._v("、"),v("code",[_._v("有或没有")]),_._v("类型的问句,除非你想得到"),v("a",{attrs:{href:"https://strcat.de/questions-with-yes-or-no-answers.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("是或否类型的回答"),v("OutboundLink")],1),_._v("。")]),_._v(" "),v("h3",{attrs:{id:"即使你很急也不要在标题写紧急"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#即使你很急也不要在标题写紧急"}},[_._v("#")]),_._v(" 即使你很急也不要在标题写"),v("code",[_._v("紧急")])]),_._v(" "),v("p",[_._v("这是你的问题,不是我们的。宣称"),v("code",[_._v("紧急")]),_._v("极有可能事与愿违:大多数黑客会直接删除无礼和自私地企图即时引起关注的问题。更严重的是,"),v("code",[_._v("紧急")]),_._v("这个字(或是其他企图引起关注的标题)通常会被垃圾信过滤器过滤掉 —— 你希望能看到你问题的人可能永远也看不到。")]),_._v(" "),v("p",[_._v("有半个例外的情况是,如果你是在一些很高调,会使黑客们兴奋的地方,也许值得这样去做。在这种情况下,如果你有时间压力,也很有礼貌地提到这点,人们也许会有兴趣回答快一点。")]),_._v(" "),v("p",[_._v("当然,这风险很大,因为黑客们兴奋的点多半与你的不同。譬如从 NASA 国际空间站(International Space Station)发这样的标题没有问题,但用自我感觉良好的慈善行为或政治原因发肯定不行。事实上,张贴诸如"),v("code",[_._v("紧急:帮我救救这个毛茸茸的小海豹!")]),_._v("肯定让你被黑客忽略或惹恼他们,即使他们认为毛茸茸的小海豹很重要。")]),_._v(" "),v("p",[_._v("如果你觉得这点很不可思议,最好再把这份指南剩下的内容多读几遍,直到你弄懂了再发文。")]),_._v(" "),v("h3",{attrs:{id:"礼多人不怪-而且有时还很有帮助"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#礼多人不怪-而且有时还很有帮助"}},[_._v("#")]),_._v(" 礼多人不怪,而且有时还很有帮助")]),_._v(" "),v("p",[_._v("彬彬有礼,多用"),v("code",[_._v("请")]),_._v("和"),v("code",[_._v("谢谢您的关注")]),_._v(",或"),v("code",[_._v("谢谢你的关照")]),_._v("。让大家都知道你对他们花时间免费提供帮助心存感激。")]),_._v(" "),v("p",[_._v("坦白说,这一点并没有比使用清晰、正确、精准且合乎语法和避免使用专用格式重要(也不能取而代之)。黑客们一般宁可读有点唐突但技术上鲜明的 Bug 报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教给我们什么来评价问题的价值的)")]),_._v(" "),v("p",[_._v("然而,如果你有一串的问题待解决,客气一点肯定会增加你得到有用回应的机会。")]),_._v(" "),v("p",[_._v("(我们注意到,自从本指南发布后,从资深黑客那里得到的唯一严重缺陷反馈,就是对预先道谢这一条。一些黑客觉得"),v("code",[_._v("先谢了")]),_._v("意味着事后就不用再感谢任何人的暗示。我们的建议是要么先说"),v("code",[_._v("先谢了")]),_._v(","),v("strong",[_._v("然后")]),_._v("事后再对回复者表示感谢,或者换种方式表达感激,譬如用"),v("code",[_._v("谢谢你的关注")]),_._v("或"),v("code",[_._v("谢谢你的关照")]),_._v("。)")]),_._v(" "),v("h3",{attrs:{id:"问题解决后-加个简短的补充说明"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#问题解决后-加个简短的补充说明"}},[_._v("#")]),_._v(" 问题解决后,加个简短的补充说明")]),_._v(" "),v("p",[_._v("问题解决后,向所有帮助过你的人发个说明,让他们知道问题是怎样解决的,并再一次向他们表示感谢。如果问题在新闻组或者邮件列表中引起了广泛关注,应该在那里贴一个说明比较恰当。")]),_._v(" "),v("p",[_._v("最理想的方式是向最初提问的话题回复此消息,并在标题中包含"),v("code",[_._v("已修正")]),_._v(","),v("code",[_._v("已解决")]),_._v("或其它同等含义的明显标记。在人来人往的邮件列表里,一个看见讨论串"),v("code",[_._v("问题 X")]),_._v("和"),v("code",[_._v("问题 X - 已解决")]),_._v("的潜在回复者就明白不用再浪费时间了(除非他个人觉得"),v("code",[_._v("问题 X")]),_._v("有趣),因此可以利用此时间去解决其它问题。")]),_._v(" "),v("p",[_._v("补充说明不必很长或是很深入;简单的一句"),v("code",[_._v("你好,原来是网线出了问题!谢谢大家 – Bill")]),_._v("比什么也不说要来的好。事实上,除非结论真的很有技术含量,否则简短可爱的小结比长篇大论更好。说明问题是怎样解决的,但大可不必将解决问题的过程复述一遍。")]),_._v(" "),v("p",[_._v("对于有深度的问题,张贴调试记录的摘要是有帮助的。描述问题的最终状态,说明是什么解决了问题,在此"),v("strong",[_._v("之后")]),_._v("才指明可以避免的盲点。避免盲点的部分应放在正确的解决方案和其它总结材料之后,而不要将此信息搞成侦探推理小说。列出那些帮助过你的名字,会让你交到更多朋友。")]),_._v(" "),v("p",[_._v("除了有礼貌和有内涵以外,这种类型的补充也有助于他人在邮件列表/新闻群组/论坛中搜索到真正解决你问题的方案,让他们也从中受益。")]),_._v(" "),v("p",[_._v("至少,这种补充有助于让每位参与协助的人因问题的解决而从中得到满足感。如果你自己不是技术专家或者黑客,那就相信我们,这种感觉对于那些你向他们求助的大师或者专家而言,是非常重要的。问题悬而未决会让人灰心;黑客们渴望看到问题被解决。好人有好报,满足他们的渴望,你会在下次提问时尝到甜头。")]),_._v(" "),v("p",[_._v("思考一下怎样才能避免他人将来也遇到类似的问题,自问写一份文件或加个常见问题(FAQ)会不会有帮助。如果是的话就将它们发给维护者。")]),_._v(" "),v("p",[_._v("在黑客中,这种良好的后继行动实际上比传统的礼节更为重要,也是你如何透过善待他人而赢得声誉的方式,这是非常有价值的资产。")]),_._v(" "),v("h2",{attrs:{id:"如何解读答案"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何解读答案"}},[_._v("#")]),_._v(" 如何解读答案")]),_._v(" "),v("p",[v("a",{attrs:{id:"rtfm"}})]),_._v(" "),v("h3",{attrs:{id:"rtfm-和-stfw-如何知道你已完全搞砸了"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#rtfm-和-stfw-如何知道你已完全搞砸了"}},[_._v("#")]),_._v(" RTFM 和 STFW:如何知道你已完全搞砸了")]),_._v(" "),v("p",[_._v("有一个古老而神圣的传统:如果你收到"),v("code",[_._v("RTFM(Read The Fucking Manual)")]),_._v("的回应,回答者认为你"),v("strong",[_._v("应该去读他妈的手册")]),_._v("。当然,基本上他是对的,你应该去读一读。")]),_._v(" "),v("p",[_._v("RTFM 有一个年轻的亲戚。如果你收到"),v("code",[_._v("STFW(Search The Fucking Web)")]),_._v("的回应,回答者认为你"),v("strong",[_._v("应该到他妈的网上搜索")]),_._v("。那人多半也是对的,去搜索一下吧。(更温和一点的说法是 "),v("strong",[v("a",{attrs:{href:"http://lmgtfy.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google 是你的朋友"),v("OutboundLink")],1)]),_._v("!)")]),_._v(" "),v("p",[_._v("在论坛,你也可能被要求去爬爬论坛的旧文。事实上,有人甚至可能热心地为你提供以前解决此问题的讨论串。但不要依赖这种关照,提问前应该先搜索一下旧文。")]),_._v(" "),v("p",[_._v("通常,用这两句之一回答你的人会给你一份包含你需要内容的手册或者一个网址,而且他们打这些字的时候也正在读着。这些答复意味着回答者认为:")]),_._v(" "),v("ul",[v("li",[v("strong",[_._v("你需要的信息非常容易获得")]),_._v(";")]),_._v(" "),v("li",[v("strong",[_._v("你自己去搜索这些信息比灌给你,能让你学到更多")]),_._v("。")])]),_._v(" "),v("p",[_._v("你不应该因此不爽;"),v("strong",[_._v("依照黑客的标准,他已经表示了对你一定程度的关注,而没有对你的要求视而不见")]),_._v("。你应该对他祖母般的慈祥表示感谢。")]),_._v(" "),v("h3",{attrs:{id:"如果还是搞不懂"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如果还是搞不懂"}},[_._v("#")]),_._v(" 如果还是搞不懂")]),_._v(" "),v("p",[_._v("如果你看不懂回应,别立刻要求对方解释。像你以前试着自己解决问题时那样(利用手册,FAQ,网络,身边的高手),先试着去搞懂他的回应。如果你真的需要对方解释,记得表现出你已经从中学到了点什么。")]),_._v(" "),v("p",[_._v("比方说,如果我回答你:"),v("code",[_._v("看来似乎是 zentry 卡住了;你应该先清除它。")]),_._v(",然后,这是一个"),v("strong",[_._v("很糟的")]),_._v("后续问题回应:"),v("code",[_._v("zentry 是什么?")]),_._v(" "),v("strong",[_._v("好")]),_._v("的问法应该是这样:"),v("code",[_._v("哦~~~我看过说明了但是只有 -z 和 -p 两个参数中提到了 zentries,而且还都没有清楚的解释如何清除它。你是指这两个中的哪一个吗?还是我看漏了什么?")])]),_._v(" "),v("h3",{attrs:{id:"处理无礼的回应"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#处理无礼的回应"}},[_._v("#")]),_._v(" 处理无礼的回应")]),_._v(" "),v("p",[_._v("很多黑客圈子中看似无礼的行为并不是存心冒犯。相反,它是直截了当,一针见血式的交流风格,这种风格更注重解决问题,而不是使人感觉舒服而却模模糊糊。")]),_._v(" "),v("p",[_._v("如果你觉得被冒犯了,试着平静地反应。如果有人真的做了出格的事,邮件列表、新闻群组或论坛中的前辈多半会招呼他。如果这"),v("strong",[_._v("没有")]),_._v("发生而你却发火了,那么你发火对象的言语可能在黑客社区中看起来是正常的,而"),v("strong",[_._v("你")]),_._v("将被视为有错的一方,这将伤害到你获取信息或帮助的机会。")]),_._v(" "),v("p",[_._v("另一方面,你偶尔真的会碰到无礼和无聊的言行。与上述相反,对真正的冒犯者狠狠地打击,用犀利的语言将其驳得体无完肤都是可以接受的。然而,在行事之前一定要非常非常的有根据。纠正无礼的言论与开始一场毫无意义的口水战仅一线之隔,黑客们自己莽撞地越线的情况并不鲜见。如果你是新手或外人,避开这种莽撞的机会并不高。如果你想得到的是信息而不是消磨时光,这时最好不要把手放在键盘上以免冒险。")]),_._v(" "),v("p",[_._v("(有些人断言很多黑客都有轻度的自闭症或亚斯伯格综合症,缺少用于润滑人类社会"),v("strong",[_._v("正常")]),_._v("交往所需的神经。这既可能是真也可能是假的。如果你自己不是黑客,兴许你认为我们脑袋有问题还能帮助你应付我们的古怪行为。只管这么干好了,我们不在乎。我们"),v("strong",[_._v("喜欢")]),_._v("我们现在这个样子,并且通常对病患标记都有站得住脚的怀疑。)")]),_._v(" "),v("p",[_._v("Jeff Bigler 的观察总结和这个相关也值得一读 ("),v("strong",[v("a",{attrs:{href:"http://www.mit.edu/~jcb/tact.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("tact filters"),v("OutboundLink")],1)]),_._v(")。")]),_._v(" "),v("p",[_._v("在下一节,我们会谈到另一个问题,当"),v("strong",[_._v("你")]),_._v("行为不当时所会受到的"),v("code",[_._v("冒犯")]),_._v("。")]),_._v(" "),v("h2",{attrs:{id:"如何避免扮演失败者"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何避免扮演失败者"}},[_._v("#")]),_._v(" 如何避免扮演失败者")]),_._v(" "),v("p",[_._v("在黑客社区的论坛中,你以本指南所描述的或类似的方式,可能会有那么几次搞砸了。而你会在公开场合中被告知你是如何搞砸的,也许攻击的言语中还会带点夹七夹八的颜色。")]),_._v(" "),v("p",[_._v("这种事发生以后,你能做的最糟糕的事莫过于哀嚎你的遭遇、宣称被言语攻击、要求道歉、高声尖叫、憋闷气、威胁诉诸法律、向其雇主报怨、不去关马桶盖等等。相反地,你该这么做:")]),_._v(" "),v("p",[_._v("熬过去,这很正常。事实上,它是有益健康且合理的。")]),_._v(" "),v("p",[_._v("社区的标准不会自行维持,它们是通过参与者积极而"),v("strong",[_._v("公开地")]),_._v("执行来维持的。不要哭嚎所有的批评都应该通过私下的邮件传送,它不是这样运作的。当有人评论你的一个说法有误或者提出不同看法时,坚持声称受到个人攻击也毫无益处,这些都是失败者的态度。")]),_._v(" "),v("p",[_._v("也有其它的黑客论坛,受过高礼节要求的误导,禁止参与者张贴任何对别人帖子挑毛病的消息,并声称"),v("code",[_._v("如果你不想帮助用户就闭嘴。")]),_._v(" 结果造成有想法的参与者纷纷离开,这么做只会使它们沦为毫无意义的唠叨与无用的技术论坛。")]),_._v(" "),v("p",[_._v("夸张的讲法是:你要的是“友善”(以上述方式)还是有用?两个里面挑一个。")]),_._v(" "),v("p",[_._v("记着:当黑客说你搞砸了,并且(无论多么刺耳)告诉你别再这样做时,他正在为关心"),v("strong",[_._v("你")]),_._v("和"),v("strong",[_._v("他的社区")]),_._v("而行动。对他而言,不理你并将你从他的生活中滤掉更简单。如果你无法做到感谢,至少要表现得有点尊严,别大声哀嚎,也别因为自己是个有戏剧性超级敏感的灵魂和自以为有资格的新来者,就指望别人像对待脆弱的洋娃娃那样对你。")]),_._v(" "),v("p",[_._v("有时候,即使你没有搞砸(或者只是在他的想像中你搞砸了),有些人也会无缘无故地攻击你本人。在这种情况下,抱怨倒是"),v("strong",[_._v("真的")]),_._v("会把问题搞砸。")]),_._v(" "),v("p",[_._v("这些来找麻烦的人要么是毫无办法但自以为是专家的不中用家伙,要么就是测试你是否真会搞砸的心理专家。其它读者要么不理睬,要么用自己的方式对付他们。这些来找麻烦的人在给他们自己找麻烦,这点你不用操心。")]),_._v(" "),v("p",[_._v("也别让自己卷入口水战,最好不要理睬大多数的口水战 —— 当然,这是在你检验它们只是口水战,并且未指出你有搞砸的地方,同时也没有巧妙地将问题真正的答案藏于其后(这也是有可能的)。")]),_._v(" "),v("h2",{attrs:{id:"不该问的问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#不该问的问题"}},[_._v("#")]),_._v(" 不该问的问题")]),_._v(" "),v("p",[_._v("以下是几个经典蠢问题,以及黑客没回答时心中所想的:")]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q1"}},[_._v("我能在哪找到 X 程序或 X 资源?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q2"}},[_._v("我怎样用 X 做 Y?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q3"}},[_._v("如何设定我的 shell 提示?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q4"}},[_._v("我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文件转换为 TeX 格式吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q5"}},[_._v("我的程序/设定/SQL 语句没有用")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q6"}},[_._v("我的 Windows 电脑有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q7"}},[_._v("我的程序不会动了,我认为系统工具 X 有问题")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q8"}},[_._v("我在安装 Linux(或者 X )时有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("问题:"),v("a",{attrs:{href:"#q9"}},[_._v("我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?")])]),_._v(" "),v("hr"),_._v(" "),v("p",[v("a",{attrs:{id:"q1"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我能在哪找到 X 程序或 X 资源?")])]),_._v(" "),v("p",[_._v("回答:就在我找到它的地方啊,白痴 —— 搜索引擎的那一头。天哪!难道还有人不会用 "),v("a",{attrs:{href:"https://www.google.com",target:"_blank",rel:"noopener noreferrer"}},[_._v("Google"),v("OutboundLink")],1),_._v(" 吗?")]),_._v(" "),v("p",[v("a",{attrs:{id:"q2"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我怎样用 X 做 Y?")])]),_._v(" "),v("p",[_._v("回答:如果你想解决的是 Y ,提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知,也对 Y 要解决的问题糊涂,还被特定形势禁锢了思维。最好忽略这种人,等他们把问题搞清楚了再说。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q3"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:如何设定我的 shell 提示??")])]),_._v(" "),v("p",[_._v("回答:如果你有足够的智慧提这个问题,你也该有足够的智慧去 "),v("a",{attrs:{href:"#RTFM"}},[_._v("RTFM")]),_._v(",然后自己去找出来。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q4"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文件转换为 TeX 格式吗?")])]),_._v(" "),v("p",[_._v("回答:试试看就知道了。如果你试过,你就知道了答案,就不用浪费我的时间了。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q5"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的{程序/设定/SQL 语句}没有用")])]),_._v(" "),v("p",[_._v("回答:这不算是问题吧,我对要我问你二十个问题才找得出你真正问题的问题没兴趣 —— 我有更有意思的事要做呢。在看到这类问题的时候,我的反应通常不外如下三种")]),_._v(" "),v("ul",[v("li",[_._v("你还有什么要补充的吗?")]),_._v(" "),v("li",[_._v("真糟糕,希望你能搞定。")]),_._v(" "),v("li",[_._v("这关我屁事?")])]),_._v(" "),v("p",[v("a",{attrs:{id:"q6"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的 Windows 电脑有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("回答:能啊,扔掉微软的垃圾,换个像 Linux 或 BSD 的开源操作系统吧。")]),_._v(" "),v("p",[_._v("注意:如果程序有官方版 Windows 或者与 Windows 有互动(如 Samba),你"),v("strong",[_._v("可以")]),_._v("问与 Windows 相关的问题,只是别对问题是由 Windows 操作系统而不是程序本身造成的回复感到惊讶, 因为 Windows 一般来说实在太烂,这种说法通常都是对的。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q7"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我的程序不会动了,我认为系统工具 X 有问题")])]),_._v(" "),v("p",[_._v("回答:你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与函数库文件有明显缺陷的人,更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据,当你这样声称时,你必须有清楚而详尽的缺陷说明文件作后盾。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q8"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我在安装 Linux(或者 X )时有问题,你能帮我吗?")])]),_._v(" "),v("p",[_._v("回答:不能,我只有亲自在你的电脑上动手才能找到毛病。还是去找你当地的 Linux 使用群组者寻求实际的指导吧(你能在"),v("a",{attrs:{href:"http://www.linux.org/groups/index.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("这儿"),v("OutboundLink")],1),_._v("找到用户群组的清单)。")]),_._v(" "),v("p",[_._v("注意:如果安装问题与某 Linux 的发行版有关,在它的邮件列表、论坛或本地用户群组中提问也许是恰当的。此时,应描述问题的准确细节。在此之前,先用 "),v("code",[_._v("Linux")]),_._v(" 和"),v("strong",[_._v("所有")]),_._v("被怀疑的硬件作关键词仔细搜索。")]),_._v(" "),v("p",[v("a",{attrs:{id:"q9"}})]),_._v(" "),v("blockquote",[v("p",[_._v("问题:我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?")])]),_._v(" "),v("p",[_._v("回答:想要这样做,说明了你是个卑鄙小人;想找个黑客帮你,说明你是个白痴!")]),_._v(" "),v("h2",{attrs:{id:"好问题与蠢问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#好问题与蠢问题"}},[_._v("#")]),_._v(" 好问题与蠢问题")]),_._v(" "),v("p",[_._v("最后,我将透过举一些例子,来说明怎样聪明的提问;同一个问题的两种问法被放在一起,一种是愚蠢的,另一种才是明智的。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我可以在哪儿找到关于 Foonly Flurbamatic 的资料?")])]),_._v(" "),v("p",[_._v("这种问法无非想得到 "),v("a",{attrs:{href:"#RTFM"}},[_._v("STFW")]),_._v(" 这样的回答。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v('我用 Google 搜索过 "Foonly Flurbamatic 2600",但是没找到有用的结果。谁知道上哪儿去找对这种设备编程的资料?')])]),_._v(" "),v("p",[_._v("这个问题已经 STFW 过了,看起来他真的遇到了麻烦。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我从 foo 项目找来的源码没法编译。它怎么这么烂?")])]),_._v(" "),v("p",[_._v("他觉得都是别人的错,这个傲慢自大的提问者。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ,但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录,我有什么做的不对的地方吗?")])]),_._v(" "),v("p",[_._v("提问者已经指明了环境,也读过了 FAQ,还列出了错误,并且他没有把问题的责任推到别人头上,他的问题值得被关注。")]),_._v(" "),v("p",[v("strong",[_._v("蠢问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我的主机板有问题了,谁来帮我?")])]),_._v(" "),v("p",[_._v("某黑客对这类问题的回答通常是:"),v("code",[_._v("好的,还要帮你拍拍背和换尿布吗?")]),_._v(",然后按下删除键。")]),_._v(" "),v("p",[v("strong",[_._v("聪明问题")]),_._v(":")]),_._v(" "),v("blockquote",[v("p",[_._v("我在 S2464 主机板上试过了 X 、 Y 和 Z ,但没什么作用,我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking,但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么?有谁知道接下来我该做些什么测试才能找出问题?")])]),_._v(" "),v("p",[_._v("这个家伙,从另一个角度来看,值得去回答他。他表现出了解决问题的能力,而不是坐等天上掉答案。")]),_._v(" "),v("p",[_._v("在最后一个问题中,注意"),v("code",[_._v("告诉我答案")]),_._v("和"),v("code",[_._v("给我启示,指出我还应该做什么诊断工作")]),_._v("之间微妙而又重要的区别。")]),_._v(" "),v("p",[_._v("事实上,后一个问题源自于 2001 年 8 月在 Linux 内核邮件列表(lkml)上的一个真实的提问。我(Eric)就是那个提出问题的人。我在 Tyan S2464 主板上观察到了这种无法解释的锁定现象,列表成员们提供了解决这一问题的重要信息。")]),_._v(" "),v("p",[_._v("通过我的提问方法,我给了别人可以咀嚼玩味的东西;我设法让人们很容易参与并且被吸引进来。我显示了自己具备和他们同等的能力,并邀请他们与我共同探讨。通过告诉他们我所走过的弯路,以避免他们再浪费时间,我也表明了对他们宝贵时间的尊重。")]),_._v(" "),v("p",[_._v("事后,当我向每个人表示感谢,并且赞赏这次良好的讨论经历的时候,一个 Linux 内核邮件列表的成员表示,他觉得我的问题得到解决并非由于我是这个列表中的"),v("strong",[_._v("名")]),_._v("人,而是因为我用了正确的方式来提问。")]),_._v(" "),v("p",[_._v("黑客从某种角度来说是拥有丰富知识但缺乏人情味的家伙;我相信他是对的,如果我"),v("strong",[_._v("像")]),_._v("个乞讨者那样提问,不论我是谁,一定会惹恼某些人或者被他们忽视。他建议我记下这件事,这直接导致了本指南的出现。")]),_._v(" "),v("h2",{attrs:{id:"如果得不到回答"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如果得不到回答"}},[_._v("#")]),_._v(" 如果得不到回答")]),_._v(" "),v("p",[_._v("如果仍得不到回答,请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。没有回应不代表你被忽视,虽然不可否认这种差别很难区分。")]),_._v(" "),v("p",[_._v("总的来说,简单地重复张贴问题是个很糟的点子。这将被视为无意义的喧闹。有点耐心,知道你问题答案的人可能生活在不同的时区,可能正在睡觉,也有可能你的问题一开始就没有组织好。")]),_._v(" "),v("p",[_._v("你可以通过其他渠道获得帮助,这些渠道通常更适合初学者的需要。")]),_._v(" "),v("p",[_._v("有许多网上的以及本地的用户群组,由热情的软件爱好者(即使他们可能从没亲自写过任何软件)组成。通常人们组建这样的团体来互相帮助并帮助新手。")]),_._v(" "),v("p",[_._v("另外,你可以向很多商业公司寻求帮助,不论公司大还是小。别为要付费才能获得帮助而感到沮丧!毕竟,假使你的汽车发动机汽缸密封圈爆掉了 —— 完全可能如此 —— 你还得把它送到修车铺,并且为维修付费。就算软件没花费你一分钱,你也不能强求技术支持总是免费的。")]),_._v(" "),v("p",[_._v("对像是 Linux 这种大众化的软件,每个开发者至少会对应到上万名用户。根本不可能由一个人来处理来自上万名用户的求助电话。要知道,即使你要为这些协助付费,和你所购买的同类软件相比,你所付出的也是微不足道的(通常封闭源代码软件的技术支持费用比开源软件的要高得多,且内容也没那么丰富)。")]),_._v(" "),v("h2",{attrs:{id:"如何更好地回答问题"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#如何更好地回答问题"}},[_._v("#")]),_._v(" 如何更好地回答问题")]),_._v(" "),v("p",[v("strong",[_._v("态度和善一点。")]),_._v(" 问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。")]),_._v(" "),v("p",[v("strong",[_._v("对初犯者私下回复。")]),_._v(" 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找常见问题都不知道。")]),_._v(" "),v("p",[v("strong",[_._v("如果你不确定,一定要说出来!")]),_._v(" 一个听起来权威的错误回复比没有还要糟,别因为听起来像个专家很好玩,就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。")]),_._v(" "),v("p",[v("strong",[_._v("如果帮不了忙,也别妨碍他。")]),_._v(" 不要在实际步骤上开玩笑,那样也许会毁了提问者的设置 —— 有些可怜的呆瓜会把它当成真的指令。")]),_._v(" "),v("p",[v("strong",[_._v("试探性的反问以引出更多的细节。")]),_._v(" 如果你做得好,提问者可以学到点东西 —— 你也可以。试试将蠢问题转变成好问题,别忘了我们都曾是新手。")]),_._v(" "),v("p",[_._v("尽管对那些懒虫抱怨一声 RTFM 是正当的,但能给出文档的链接(即使只是建议个 Google 搜索关键词)会更好。")]),_._v(" "),v("p",[v("strong",[_._v("如果你决定回答,就请给出好的答案。")]),_._v(" 当别人正在用错误的工具或方法时别建议笨拙的权宜之计(workaround),应推荐更好的工具,重新界定问题。")]),_._v(" "),v("p",[v("strong",[_._v("正面地回答问题!")]),_._v(" 如果这个提问者已经很深入的研究而且也表明已经试过 X 、 Y 、 Z 、 A 、 B 、 C 但没得到结果,回答 "),v("code",[_._v("试试看 A 或是 B")]),_._v(" 或者 "),v("code",[_._v("试试 X 、 Y 、 Z 、 A 、 B 、 C")]),_._v(" 并附上一个链接一点用都没有。")]),_._v(" "),v("p",[v("strong",[_._v("帮助你的社区从问题中学习。")]),_._v(" 当回复一个好问题时,问问自己"),v("code",[_._v("如何修改相关文件或常见问题文件以免再次解答同样的问题?")]),_._v(",接着再向文件维护者发一份补丁。")]),_._v(" "),v("p",[_._v("如果你在研究一番后才作出了回答,"),v("strong",[_._v("展现你的技巧而不是直接端出结果")]),_._v("。毕竟"),v("code",[_._v("授人以鱼不如授人以渔")]),_._v("。")]),_._v(" "),v("h2",{attrs:{id:"相关资源"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#相关资源"}},[_._v("#")]),_._v(" 相关资源")]),_._v(" "),v("p",[_._v("如果你需要个人电脑、Unix 系统和网络如何运作的基础知识,参阅 "),v("a",{attrs:{href:"http://en.tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Unix 系统和网络基本原理"),v("OutboundLink")],1),_._v("。")]),_._v(" "),v("p",[_._v("当你发布软件或补丁时,试着按"),v("a",{attrs:{href:"http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/index.html",target:"_blank",rel:"noopener noreferrer"}},[_._v("软件发布实践"),v("OutboundLink")],1),_._v("操作。")]),_._v(" "),v("h2",{attrs:{id:"鸣谢"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#鸣谢"}},[_._v("#")]),_._v(" 鸣谢")]),_._v(" "),v("p",[_._v("Evelyn Mitchel 贡献了一些愚蠢问题例子并启发了编写"),v("code",[_._v("如何更好地回答问题")]),_._v("这一节, Mikhail Ramendik 贡献了一些特别有价值的建议和改进。")])])}),[],!1,null,null,null);v.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/47.36c619b7.js b/docs/assets/js/47.e1e7b386.js similarity index 97% rename from docs/assets/js/47.36c619b7.js rename to docs/assets/js/47.e1e7b386.js index 263e6256..08ad5961 100644 --- a/docs/assets/js/47.36c619b7.js +++ b/docs/assets/js/47.e1e7b386.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{320:function(e,r,t){"use strict";t.r(r);var o=t(14),n=Object(o.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"_1-0-0-2023-03-23"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-0-0-2023-03-23"}},[e._v("#")]),e._v(" 1.0.0 (2023-03-23)")]),e._v(" "),r("p",[e._v("这是 crane4j 的第一个正式版本,如果遇到问题可以在群内或 issues 中反馈,作者会尽快响应。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/1",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供基于 Guava 的 LoadingCache 的缓存支持"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/20",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加默认的组合注解扩展包"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/17",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持使用Spring的@Order注解对装配操作排序"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/14",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持在注解中通过 beanName 引用 Spring 上下文中的组件"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/8",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加扩展模块,支持基于 MybatisPlus 自动生成表查询数据源"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/25",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构装配处理器,并统一为所有装配操作提供一对一、一对多、多对多映射支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/23",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构并完善缓存功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加容器工厂组件以隔离和丰富获取数据源容器的渠道"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/10",target:"_blank",rel:"noopener noreferrer"}},[e._v("将注解分离至独立的 crane4j-annotation 模块"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Test")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/1",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充 MultiKeyAssembleOperationHandler 的测试用例"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/15",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加示例项目"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("docs")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/18",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加官方站点配置"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/13",target:"_blank",rel:"noopener noreferrer"}},[e._v("代码注释国际化"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/2",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 crane4j 的官方文档站点"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("chore")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/9",target:"_blank",rel:"noopener noreferrer"}},[e._v("重命名 groupId 为 cn.crane4j"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/12",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加自动化 CI 流程"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-1-0-2023-03-30"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-0-2023-03-30"}},[e._v("#")]),e._v(" 1.1.0 (2023-03-30)")]),e._v(" "),r("p",[e._v("这一个重构与增强版本,增强了一些新功能,并且调整了一部分 api 的使用方式。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/2",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("core模块应该默认支持ognl表达式"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/30",target:"_blank",rel:"noopener noreferrer"}},[e._v("简化"),r("code",[e._v("@Mapping")]),e._v("配置,可以在一个属性同时配置src和ref"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/27",target:"_blank",rel:"noopener noreferrer"}},[e._v("字段映射支持以链式操作符获取或设置多级嵌套对象的属性"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供基于 Guava 的 LoadingCache 的缓存支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/33",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持通过 "),r("code",[e._v("@ContainerConstant")]),e._v(" 注解的配置,反转基于常量类构建的容器键值"),r("OutboundLink")],1)])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/23",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构并完善缓存功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/28",target:"_blank",rel:"noopener noreferrer"}},[e._v("将starter模块中的部分组件功能分离为核心模块中的独立组件"),r("OutboundLink")],1)])]),e._v(" "),r("p",[r("strong",[e._v("docs")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/31",target:"_blank",rel:"noopener noreferrer"}},[e._v("文档重构"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-2-0-2023-04-09"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-0-2023-04-09"}},[e._v("#")]),e._v(" 1.2.0 (2023-04-09)")]),e._v(" "),r("p",[e._v("这一个重构版本,增强了一些新功能,并且调整了 MybatisPlus 扩展的引入方式,如果已经使用了 MybatisPlus 插件,则需要按文档重新引入。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/3",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/21",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持直接填充 Map 类型的数据"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/36",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 "),r("code",[e._v("@AssembleMp")]),e._v(" 注解,为基于 MP 的数据源提供更好的支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/22",target:"_blank",rel:"noopener noreferrer"}},[e._v("允许自定义注解,支持解析自定义的配置规则"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/37",target:"_blank",rel:"noopener noreferrer"}},[e._v("MpBaseMapperContainerRegister支持懒加载"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/39",target:"_blank",rel:"noopener noreferrer"}},[e._v("将 "),r("code",[e._v("@Assemble")]),e._v(" 和 "),r("code",[e._v("@Disassemble")]),e._v(" 的解析逻辑分离到独立的注解处理器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/28",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构项目结构,提供不同环境下的最小依赖"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Fix")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/38",target:"_blank",rel:"noopener noreferrer"}},[e._v("当Bean被spring代理时,调用方法数据源容器报错"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-3-0-alpha-2023-05-10"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-0-alpha-2023-05-10"}},[e._v("#")]),e._v(" 1.3.0-ALPHA (2023-05-10)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("1.3.0")]),e._v(" 的预览版本,重构和增强了一些已有功能,并添加了一些新的功能。")]),e._v(" "),r("p",[e._v("其中,基于新特性"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/44",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加基于接口代理的填充方法"),r("OutboundLink")],1),e._v(",crane4j 将更好的支持处理 "),r("code",[e._v("JSONObject")]),e._v(" 或 "),r("code",[e._v("Map")]),e._v(" 类型的非 "),r("code",[e._v("JavaBean")]),e._v(" 对象。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/35",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 "),r("code",[e._v("@AssembleEnum")]),e._v(" 注解,对枚举类型数据源提供更好的支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/61",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个不基于 ThreadLocal 的动态数据源容器提供者"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/49",target:"_blank",rel:"noopener noreferrer"}},[e._v("代理填充方法支持设置临时容器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/55",target:"_blank",rel:"noopener noreferrer"}},[e._v("OperatorProxyFactory中代理方法的生成也应当支持多种策略"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/48",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持通过 Spring 依赖注入获取被 "),r("code",[e._v("@Operator")]),e._v(" 注解的接口的代理对象"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/50",target:"_blank",rel:"noopener noreferrer"}},[e._v("装配操作中的容器支持懒加载"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/44",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加基于接口代理的填充方法"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/41",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个默认的可配置容器注册者实现"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/70",target:"_blank",rel:"noopener noreferrer"}},[e._v("减少对 Hutool 的依赖"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/59",target:"_blank",rel:"noopener noreferrer"}},[e._v("移除 OperationAnnotationResolver 级别的配置缓存"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/45",target:"_blank",rel:"noopener noreferrer"}},[e._v("配置解析器应当支持所有的AnnotatedElement类型对象的注解配置"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Test")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/67",target:"_blank",rel:"noopener noreferrer"}},[e._v("提高测试覆盖率"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/72",target:"_blank",rel:"noopener noreferrer"}},[e._v("MybatisPlus相关扩展的测试用例数据库更换为H2"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[e._v("修复了引入 "),r("code",[e._v("crane4j-spring-boot-starter")]),e._v(" 时的一些自动装配问题;")])]),e._v(" "),r("p",[r("strong",[e._v("Doc")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/34",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充文档,如何在非 spring 环境和 spring 环境使用 crane4j"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_2-0-0-alpha-2023-07-08"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-0-alpha-2023-07-08"}},[e._v("#")]),e._v(" 2.0.0-ALPHA (2023-07-08)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("2.0.0")]),e._v(" 的预览版本,基于 "),r("code",[e._v("1.3.0-ALPHA")]),e._v(" 升级而来。")]),e._v(" "),r("p",[e._v("项目进行了一次范围较大的重构,优化了大量的代码与逻辑,部分 API 可能不向下兼容。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/97",target:"_blank",rel:"noopener noreferrer"}},[e._v("优化 "),r("code",[e._v("@ContainerMethod")]),e._v(" 注解在类上的配置方式"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/84",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加一个全局的排序器静态单例,用于同时支持 Spring 的 "),r("code",[e._v("@Order")]),e._v(" 与 Crane4j 的 "),r("code",[e._v("Sorted")]),e._v(" 接口"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/76",target:"_blank",rel:"noopener noreferrer"}},[r("code",[e._v("ConstantContainer")]),e._v(" 支持刷新缓存内容"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/49",target:"_blank",rel:"noopener noreferrer"}},[e._v("代理填充方法支持设置临时容器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/41",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个默认的可配置容器注册者实现"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/86",target:"_blank",rel:"noopener noreferrer"}},[e._v("2.0 升级重构计划"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/85",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构容器与装配操作配置的绑定过程"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/81",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构全局配置类的容器管理功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/63",target:"_blank",rel:"noopener noreferrer"}},[e._v("装配操作可以指定数据源容器的加载策略"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/45",target:"_blank",rel:"noopener noreferrer"}},[e._v("配置解析器应当支持所有的AnnotatedElement类型对象的注解配置"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[e._v("移除了 "),r("code",[e._v("AbstractCacheablePropertyOperator")]),e._v(" ,缓存功能分离至独立的 "),r("code",[e._v("CacheablePropertyOperator")]),e._v(" 装饰器;")])]),e._v(" "),r("p",[r("strong",[e._v("Doc")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/34",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充文档,如何在非 spring 环境和 spring 环境使用 crane4j"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_2-0-0-bate-2023-07-30"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-0-bate-2023-07-30"}},[e._v("#")]),e._v(" 2.0.0-BATE (2023-07-30)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("2.0.0")]),e._v(" 的第二个预览版本,在上一版本的基础上修复了一些 bug,并添加了少量新功能。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Fix")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/77",target:"_blank",rel:"noopener noreferrer"}},[e._v("为基于 "),r("code",[e._v("ConstantContainer")]),e._v(" 的枚举、常量容器提供独立的"),r("code",[e._v("Builder")]),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/113",target:"_blank",rel:"noopener noreferrer"}},[e._v("启用全局切面后,springboot 项目启动报错"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/114",target:"_blank",rel:"noopener noreferrer"}},[e._v("在方法添加 "),r("code",[e._v("@AutoOperate")]),e._v(" 后,若方法不指定填充对象类型,且返回值为空时报错"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/116",target:"_blank",rel:"noopener noreferrer"}},[e._v("在各个组件中由于参数/逻辑校验不通过而抛出异常时,异常需要更详细的信息"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/107",target:"_blank",rel:"noopener noreferrer"}},[e._v("一些关键操作通过 debug 级别的日志输出执行时间"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Feat")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/100",target:"_blank",rel:"noopener noreferrer"}},[e._v("当在注解中不指定 key 属性时,允许将当前对象作为 key 值"),r("OutboundLink")],1),e._v(";")])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{320:function(e,r,t){"use strict";t.r(r);var o=t(14),n=Object(o.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"_1-0-0-2023-03-23"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-0-0-2023-03-23"}},[e._v("#")]),e._v(" 1.0.0 (2023-03-23)")]),e._v(" "),r("p",[e._v("这是 crane4j 的第一个正式版本,如果遇到问题可以在群内或 issues 中反馈,作者会尽快响应。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/1",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供基于 Guava 的 LoadingCache 的缓存支持"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/20",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加默认的组合注解扩展包"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/17",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持使用Spring的@Order注解对装配操作排序"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/14",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持在注解中通过 beanName 引用 Spring 上下文中的组件"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/8",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加扩展模块,支持基于 MybatisPlus 自动生成表查询数据源"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/25",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构装配处理器,并统一为所有装配操作提供一对一、一对多、多对多映射支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/23",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构并完善缓存功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加容器工厂组件以隔离和丰富获取数据源容器的渠道"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/10",target:"_blank",rel:"noopener noreferrer"}},[e._v("将注解分离至独立的 crane4j-annotation 模块"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Test")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/1",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充 MultiKeyAssembleOperationHandler 的测试用例"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/15",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加示例项目"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("docs")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/18",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加官方站点配置"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/13",target:"_blank",rel:"noopener noreferrer"}},[e._v("代码注释国际化"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/2",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 crane4j 的官方文档站点"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("chore")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/9",target:"_blank",rel:"noopener noreferrer"}},[e._v("重命名 groupId 为 cn.crane4j"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/12",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加自动化 CI 流程"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-1-0-2023-03-30"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-0-2023-03-30"}},[e._v("#")]),e._v(" 1.1.0 (2023-03-30)")]),e._v(" "),r("p",[e._v("这一个重构与增强版本,增强了一些新功能,并且调整了一部分 api 的使用方式。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/2",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("core模块应该默认支持ognl表达式"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/30",target:"_blank",rel:"noopener noreferrer"}},[e._v("简化"),r("code",[e._v("@Mapping")]),e._v("配置,可以在一个属性同时配置src和ref"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/27",target:"_blank",rel:"noopener noreferrer"}},[e._v("字段映射支持以链式操作符获取或设置多级嵌套对象的属性"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/24",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供基于 Guava 的 LoadingCache 的缓存支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/33",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持通过 "),r("code",[e._v("@ContainerConstant")]),e._v(" 注解的配置,反转基于常量类构建的容器键值"),r("OutboundLink")],1)])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/23",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构并完善缓存功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/28",target:"_blank",rel:"noopener noreferrer"}},[e._v("将starter模块中的部分组件功能分离为核心模块中的独立组件"),r("OutboundLink")],1)])]),e._v(" "),r("p",[r("strong",[e._v("docs")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/31",target:"_blank",rel:"noopener noreferrer"}},[e._v("文档重构"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-2-0-2023-04-09"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-0-2023-04-09"}},[e._v("#")]),e._v(" 1.2.0 (2023-04-09)")]),e._v(" "),r("p",[e._v("这一个重构版本,增强了一些新功能,并且调整了 MybatisPlus 扩展的引入方式,如果已经使用了 MybatisPlus 插件,则需要按文档重新引入。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/3",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/21",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持直接填充 Map 类型的数据"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/36",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 "),r("code",[e._v("@AssembleMp")]),e._v(" 注解,为基于 MP 的数据源提供更好的支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/22",target:"_blank",rel:"noopener noreferrer"}},[e._v("允许自定义注解,支持解析自定义的配置规则"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/37",target:"_blank",rel:"noopener noreferrer"}},[e._v("MpBaseMapperContainerRegister支持懒加载"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/39",target:"_blank",rel:"noopener noreferrer"}},[e._v("将 "),r("code",[e._v("@Assemble")]),e._v(" 和 "),r("code",[e._v("@Disassemble")]),e._v(" 的解析逻辑分离到独立的注解处理器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/28",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构项目结构,提供不同环境下的最小依赖"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Fix")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/38",target:"_blank",rel:"noopener noreferrer"}},[e._v("当Bean被spring代理时,调用方法数据源容器报错"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_1-3-0-alpha-2023-05-10"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-0-alpha-2023-05-10"}},[e._v("#")]),e._v(" 1.3.0-ALPHA (2023-05-10)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("1.3.0")]),e._v(" 的预览版本,重构和增强了一些已有功能,并添加了一些新的功能。")]),e._v(" "),r("p",[e._v("其中,基于新特性"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/44",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加基于接口代理的填充方法"),r("OutboundLink")],1),e._v(",crane4j 将更好的支持处理 "),r("code",[e._v("JSONObject")]),e._v(" 或 "),r("code",[e._v("Map")]),e._v(" 类型的非 "),r("code",[e._v("JavaBean")]),e._v(" 对象。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/35",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供 "),r("code",[e._v("@AssembleEnum")]),e._v(" 注解,对枚举类型数据源提供更好的支持"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/61",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个不基于 ThreadLocal 的动态数据源容器提供者"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/49",target:"_blank",rel:"noopener noreferrer"}},[e._v("代理填充方法支持设置临时容器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/55",target:"_blank",rel:"noopener noreferrer"}},[e._v("OperatorProxyFactory中代理方法的生成也应当支持多种策略"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/48",target:"_blank",rel:"noopener noreferrer"}},[e._v("支持通过 Spring 依赖注入获取被 "),r("code",[e._v("@Operator")]),e._v(" 注解的接口的代理对象"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/50",target:"_blank",rel:"noopener noreferrer"}},[e._v("装配操作中的容器支持懒加载"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/44",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加基于接口代理的填充方法"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/41",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个默认的可配置容器注册者实现"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/70",target:"_blank",rel:"noopener noreferrer"}},[e._v("减少对 Hutool 的依赖"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/59",target:"_blank",rel:"noopener noreferrer"}},[e._v("移除 OperationAnnotationResolver 级别的配置缓存"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/45",target:"_blank",rel:"noopener noreferrer"}},[e._v("配置解析器应当支持所有的AnnotatedElement类型对象的注解配置"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Test")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/67",target:"_blank",rel:"noopener noreferrer"}},[e._v("提高测试覆盖率"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/72",target:"_blank",rel:"noopener noreferrer"}},[e._v("MybatisPlus相关扩展的测试用例数据库更换为H2"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[e._v("修复了引入 "),r("code",[e._v("crane4j-spring-boot-starter")]),e._v(" 时的一些自动装配问题;")])]),e._v(" "),r("p",[r("strong",[e._v("Doc")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/34",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充文档,如何在非 spring 环境和 spring 环境使用 crane4j"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_2-0-0-alpha-2023-07-08"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-0-alpha-2023-07-08"}},[e._v("#")]),e._v(" 2.0.0-ALPHA (2023-07-08)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("2.0.0")]),e._v(" 的预览版本,基于 "),r("code",[e._v("1.3.0-ALPHA")]),e._v(" 升级而来。")]),e._v(" "),r("p",[e._v("项目进行了一次范围较大的重构,优化了大量的代码与逻辑,部分 API 可能不向下兼容。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Feature")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/97",target:"_blank",rel:"noopener noreferrer"}},[e._v("优化 "),r("code",[e._v("@ContainerMethod")]),e._v(" 注解在类上的配置方式"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/84",target:"_blank",rel:"noopener noreferrer"}},[e._v("添加一个全局的排序器静态单例,用于同时支持 Spring 的 "),r("code",[e._v("@Order")]),e._v(" 与 Crane4j 的 "),r("code",[e._v("Sorted")]),e._v(" 接口"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/76",target:"_blank",rel:"noopener noreferrer"}},[r("code",[e._v("ConstantContainer")]),e._v(" 支持刷新缓存内容"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/49",target:"_blank",rel:"noopener noreferrer"}},[e._v("代理填充方法支持设置临时容器"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/41",target:"_blank",rel:"noopener noreferrer"}},[e._v("提供一个默认的可配置容器注册者实现"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/86",target:"_blank",rel:"noopener noreferrer"}},[e._v("2.0 升级重构计划"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/85",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构容器与装配操作配置的绑定过程"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/81",target:"_blank",rel:"noopener noreferrer"}},[e._v("重构全局配置类的容器管理功能"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/63",target:"_blank",rel:"noopener noreferrer"}},[e._v("装配操作可以指定数据源容器的加载策略"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/45",target:"_blank",rel:"noopener noreferrer"}},[e._v("配置解析器应当支持所有的AnnotatedElement类型对象的注解配置"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[e._v("移除了 "),r("code",[e._v("AbstractCacheablePropertyOperator")]),e._v(" ,缓存功能分离至独立的 "),r("code",[e._v("CacheablePropertyOperator")]),e._v(" 装饰器;")])]),e._v(" "),r("p",[r("strong",[e._v("Doc")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/34",target:"_blank",rel:"noopener noreferrer"}},[e._v("补充文档,如何在非 spring 环境和 spring 环境使用 crane4j"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("h2",{attrs:{id:"_2-0-0-bate-2023-07-30"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-0-bate-2023-07-30"}},[e._v("#")]),e._v(" 2.0.0-BATE (2023-07-30)")]),e._v(" "),r("p",[e._v("这是 "),r("code",[e._v("2.0.0")]),e._v(" 的第二个预览版本,在上一版本的基础上修复了一些 bug,并添加了一些新功能。")]),e._v(" "),r("p",[e._v("具体内容参见:"),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/milestone/4",target:"_blank",rel:"noopener noreferrer"}},[e._v("Milestone"),r("OutboundLink")],1),e._v("。")]),e._v(" "),r("p",[r("strong",[e._v("Fix")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/77",target:"_blank",rel:"noopener noreferrer"}},[e._v("为基于 "),r("code",[e._v("ConstantContainer")]),e._v(" 的枚举、常量容器提供独立的"),r("code",[e._v("Builder")]),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/113",target:"_blank",rel:"noopener noreferrer"}},[e._v("启用全局切面后,springboot 项目启动报错"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/114",target:"_blank",rel:"noopener noreferrer"}},[e._v("在方法添加 "),r("code",[e._v("@AutoOperate")]),e._v(" 后,若方法不指定填充对象类型,且返回值为空时报错"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Refactor")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/116",target:"_blank",rel:"noopener noreferrer"}},[e._v("在各个组件中由于参数/逻辑校验不通过而抛出异常时,异常需要更详细的信息"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/107",target:"_blank",rel:"noopener noreferrer"}},[e._v("一些关键操作通过 debug 级别的日志输出执行时间"),r("OutboundLink")],1),e._v(";")])]),e._v(" "),r("p",[r("strong",[e._v("Feat")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/100",target:"_blank",rel:"noopener noreferrer"}},[e._v("当在注解中不指定 key 属性时,允许将当前对象作为 key 值"),r("OutboundLink")],1),e._v(";")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/issues/105",target:"_blank",rel:"noopener noreferrer"}},[r("code",[e._v("ReflectivePropertyOperator")]),e._v(" 在没有找到 setter 或者 getter 方法时,应当支持直接基于属性进行读写"),r("OutboundLink")],1),e._v(";")])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/5.8863bfca.js b/docs/assets/js/5.954cca76.js similarity index 88% rename from docs/assets/js/5.8863bfca.js rename to docs/assets/js/5.954cca76.js index 43023bd1..3368db11 100644 --- a/docs/assets/js/5.8863bfca.js +++ b/docs/assets/js/5.954cca76.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{256:function(e,t,a){},279:function(e,t,a){"use strict";a(256)},283:function(e,t,a){"use strict";a.r(t);var o={name:"CodeGroup",data:()=>({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.activateCodeTab(e)}},mounted(){this.loadTabs()},methods:{changeCodeTab(e){this.activeCodeTabIndex=e},loadTabs(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab(e){this.codeTabs.forEach(e=>{e.elm&&e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},s=(a(279),a(14)),c=Object(s.a)(o,(function(){var e=this,t=e._self._c;return t("ClientOnly",[t("div",{staticClass:"theme-code-group"},[t("div",{staticClass:"theme-code-group__nav"},[t("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(a,o){return t("li",{key:a.title,staticClass:"theme-code-group__li"},[t("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(a.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?t("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{254:function(e,t,a){},277:function(e,t,a){"use strict";a(254)},282:function(e,t,a){"use strict";a.r(t);var o={name:"CodeGroup",data:()=>({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.activateCodeTab(e)}},mounted(){this.loadTabs()},methods:{changeCodeTab(e){this.activeCodeTabIndex=e},loadTabs(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab(e){this.codeTabs.forEach(e=>{e.elm&&e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},s=(a(277),a(14)),c=Object(s.a)(o,(function(){var e=this,t=e._self._c;return t("ClientOnly",[t("div",{staticClass:"theme-code-group"},[t("div",{staticClass:"theme-code-group__nav"},[t("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(a,o){return t("li",{key:a.title,staticClass:"theme-code-group__li"},[t("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(a.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?t("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/7.6eee443f.js b/docs/assets/js/7.cc02efaa.js similarity index 98% rename from docs/assets/js/7.6eee443f.js rename to docs/assets/js/7.cc02efaa.js index 37a87b53..da7377ca 100644 --- a/docs/assets/js/7.6eee443f.js +++ b/docs/assets/js/7.cc02efaa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{273:function(e,r,_){e.exports=_.p+"assets/img/image-20230220150040070.63150c20.png"},306:function(e,r,_){"use strict";_.r(r);var t=_(14),v=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("p",[r("img",{attrs:{src:_(273),alt:"image-20230220150040070"}})]),e._v(" "),r("h2",{attrs:{id:"_1-1-1-为什么写"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-1-为什么写"}},[e._v("#")]),e._v(" 1.1.1.为什么写?")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 是由 "),r("code",[e._v("crane")]),e._v(" 框架发展而来。最初,我在公司开发中遇到了大量重复的字段填充需求,这些需求与核心业务无关,只是一些重复的关联查询操作。我厌倦了频繁的联查和手动赋值,于是花了时间添加了一个基于 "),r("code",[e._v("MybatisPlus")]),e._v(" 的小插件,用于自动查询并填充字段值。")]),e._v(" "),r("p",[e._v("随着时间推移,这个插件功能逐渐丰富,我还加入了对枚举和常量的转换支持,并实现了基于切面的自动填充功能。最终,这个插件发展成了一个独立的框架,即 "),r("code",[e._v("crane")]),e._v(",并在生产环境中广泛使用。")]),e._v(" "),r("p",[e._v("在 2022 年初,我对 "),r("code",[e._v("crane")]),e._v(" 框架进行了重构,并将其上传到 "),r("code",[e._v("Gitee")]),e._v(",形成了 "),r("a",{attrs:{href:"https://github.com/Createsequence/crane",target:"_blank",rel:"noopener noreferrer"}},[r("code",[e._v("crane")]),r("OutboundLink")],1),e._v(" 项目。经过半年多的更新,"),r("code",[e._v("crane")]),e._v(" 的功能逐渐稳定,但早期设计的不足导致扩展困难。因此,我重新梳理了功能,并决定在保留 "),r("code",[e._v("crane")]),e._v(" 功能和概念的基础上进行彻底的重构,从而诞生了现在的 "),r("code",[e._v("crane4j")]),e._v("。")]),e._v(" "),r("p",[e._v("相较于前身 "),r("code",[e._v("crane")]),e._v(","),r("code",[e._v("crane4j")]),e._v(" 的代码更加健壮,设计更合理,功能更强大,使用更灵活。")]),e._v(" "),r("h2",{attrs:{id:"_1-1-2-它解决了什么问题"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-2-它解决了什么问题"}},[e._v("#")]),e._v(" 1.1.2.它解决了什么问题?")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 是一套基于注解的数据填充框架,“根据 A 的 key 值拿到 B,再把 B 的属性映射到 A” 就是 "),r("code",[e._v("crane4j")]),e._v(" 的核心功能。")]),e._v(" "),r("p",[e._v("在日常开发中,我们经常需要进行繁琐的数据组装工作,例如处理字典项、配置项、枚举常量,甚至进行关联数据的查询。这些数据来自不同的来源,与核心业务无关,但需要编写冗长的样板代码来处理,令人感到烦恼。")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 为了解决这个问题而生,它支持通过简单的注解配置,优雅而高效地完成不同数据源、数据类型和字段的数据填充。这样,我们就能够省去繁琐的字段填充工作,专注于核心业务的实现。")]),e._v(" "),r("h2",{attrs:{id:"_1-1-3-它有什么特性"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-3-它有什么特性"}},[e._v("#")]),e._v(" 1.1.3.它有什么特性?")]),e._v(" "),r("ul",[r("li",[r("strong",[e._v("多样的数据源支持")]),e._v(":支持枚举、键值对缓存和方法作为数据源,也可通过简单的自定义扩展兼容更多类型的数据源,并提供对所有数据源的缓存支持;")]),e._v(" "),r("li",[r("strong",[e._v("强大的字段映射能力")]),e._v(":通过注解即可完成不同类型字段的自动映射转换,还支持包括模板、排序、分组和嵌套对象填充等功能;")]),e._v(" "),r("li",[r("strong",[e._v("高度可扩展")]),e._v(":用户可以自由替换所有主要组件,结合 Spring 的依赖注入可实现轻松优雅的自定义扩展;")]),e._v(" "),r("li",[r("strong",[e._v("丰富的可选功能")]),e._v(":提供额外的自动填充方法返回值和方法入参参数,多线程填充,自定义注解和表达式,数据库框架插件等可选功能;")]),e._v(" "),r("li",[r("strong",[e._v("开箱即用")]),e._v(":简单配置即可与 spring/springboot 快速集成,也支持在非 spring 环境中使用;")])]),e._v(" "),r("h2",{attrs:{id:"_1-1-4-如何使用"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-4-如何使用"}},[e._v("#")]),e._v(" 1.1.4.如何使用?")]),e._v(" "),r("p",[e._v("想要快速体验 "),r("code",[e._v("crane4j")]),e._v(",请阅读快速开始一章,如果想要进一步了解和使用 "),r("code",[e._v("crane4j")]),e._v(",可以按推荐目录顺序阅读文档。")]),e._v(" "),r("p",[e._v("源码中记录每个类都有对应的测试用例,如果仍然感觉不好理解,可以在把源码中的示例模块 "),r("code",[e._v("crane4j-example")]),e._v(" ("),r("a",{attrs:{href:"https://gitee.com/CreateSequence/crane4j/tree/dev/crane4j-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("Gitee"),r("OutboundLink")],1),e._v(" / "),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/tree/dev/crane4j-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("GitHub"),r("OutboundLink")],1),e._v(") 拉到本地运行一下,里面有针对某些比较复杂的功能的集成测试,或许会有助于理解和使用对应功能。")])])}),[],!1,null,null,null);r.default=v.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{273:function(e,r,_){e.exports=_.p+"assets/img/image-20230220150040070.63150c20.png"},292:function(e,r,_){"use strict";_.r(r);var t=_(14),v=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("p",[r("img",{attrs:{src:_(273),alt:"image-20230220150040070"}})]),e._v(" "),r("h2",{attrs:{id:"_1-1-1-为什么写"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-1-为什么写"}},[e._v("#")]),e._v(" 1.1.1.为什么写?")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 是由 "),r("code",[e._v("crane")]),e._v(" 框架发展而来。最初,我在公司开发中遇到了大量重复的字段填充需求,这些需求与核心业务无关,只是一些重复的关联查询操作。我厌倦了频繁的联查和手动赋值,于是花了时间添加了一个基于 "),r("code",[e._v("MybatisPlus")]),e._v(" 的小插件,用于自动查询并填充字段值。")]),e._v(" "),r("p",[e._v("随着时间推移,这个插件功能逐渐丰富,我还加入了对枚举和常量的转换支持,并实现了基于切面的自动填充功能。最终,这个插件发展成了一个独立的框架,即 "),r("code",[e._v("crane")]),e._v(",并在生产环境中广泛使用。")]),e._v(" "),r("p",[e._v("在 2022 年初,我对 "),r("code",[e._v("crane")]),e._v(" 框架进行了重构,并将其上传到 "),r("code",[e._v("Gitee")]),e._v(",形成了 "),r("a",{attrs:{href:"https://github.com/Createsequence/crane",target:"_blank",rel:"noopener noreferrer"}},[r("code",[e._v("crane")]),r("OutboundLink")],1),e._v(" 项目。经过半年多的更新,"),r("code",[e._v("crane")]),e._v(" 的功能逐渐稳定,但早期设计的不足导致扩展困难。因此,我重新梳理了功能,并决定在保留 "),r("code",[e._v("crane")]),e._v(" 功能和概念的基础上进行彻底的重构,从而诞生了现在的 "),r("code",[e._v("crane4j")]),e._v("。")]),e._v(" "),r("p",[e._v("相较于前身 "),r("code",[e._v("crane")]),e._v(","),r("code",[e._v("crane4j")]),e._v(" 的代码更加健壮,设计更合理,功能更强大,使用更灵活。")]),e._v(" "),r("h2",{attrs:{id:"_1-1-2-它解决了什么问题"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-2-它解决了什么问题"}},[e._v("#")]),e._v(" 1.1.2.它解决了什么问题?")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 是一套基于注解的数据填充框架,“根据 A 的 key 值拿到 B,再把 B 的属性映射到 A” 就是 "),r("code",[e._v("crane4j")]),e._v(" 的核心功能。")]),e._v(" "),r("p",[e._v("在日常开发中,我们经常需要进行繁琐的数据组装工作,例如处理字典项、配置项、枚举常量,甚至进行关联数据的查询。这些数据来自不同的来源,与核心业务无关,但需要编写冗长的样板代码来处理,令人感到烦恼。")]),e._v(" "),r("p",[r("code",[e._v("crane4j")]),e._v(" 为了解决这个问题而生,它支持通过简单的注解配置,优雅而高效地完成不同数据源、数据类型和字段的数据填充。这样,我们就能够省去繁琐的字段填充工作,专注于核心业务的实现。")]),e._v(" "),r("h2",{attrs:{id:"_1-1-3-它有什么特性"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-3-它有什么特性"}},[e._v("#")]),e._v(" 1.1.3.它有什么特性?")]),e._v(" "),r("ul",[r("li",[r("strong",[e._v("多样的数据源支持")]),e._v(":支持枚举、键值对缓存和方法作为数据源,也可通过简单的自定义扩展兼容更多类型的数据源,并提供对所有数据源的缓存支持;")]),e._v(" "),r("li",[r("strong",[e._v("强大的字段映射能力")]),e._v(":通过注解即可完成不同类型字段的自动映射转换,还支持包括模板、排序、分组和嵌套对象填充等功能;")]),e._v(" "),r("li",[r("strong",[e._v("高度可扩展")]),e._v(":用户可以自由替换所有主要组件,结合 Spring 的依赖注入可实现轻松优雅的自定义扩展;")]),e._v(" "),r("li",[r("strong",[e._v("丰富的可选功能")]),e._v(":提供额外的自动填充方法返回值和方法入参参数,多线程填充,自定义注解和表达式,数据库框架插件等可选功能;")]),e._v(" "),r("li",[r("strong",[e._v("开箱即用")]),e._v(":简单配置即可与 spring/springboot 快速集成,也支持在非 spring 环境中使用;")])]),e._v(" "),r("h2",{attrs:{id:"_1-1-4-如何使用"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-4-如何使用"}},[e._v("#")]),e._v(" 1.1.4.如何使用?")]),e._v(" "),r("p",[e._v("想要快速体验 "),r("code",[e._v("crane4j")]),e._v(",请阅读快速开始一章,如果想要进一步了解和使用 "),r("code",[e._v("crane4j")]),e._v(",可以按推荐目录顺序阅读文档。")]),e._v(" "),r("p",[e._v("源码中记录每个类都有对应的测试用例,如果仍然感觉不好理解,可以在把源码中的示例模块 "),r("code",[e._v("crane4j-example")]),e._v(" ("),r("a",{attrs:{href:"https://gitee.com/CreateSequence/crane4j/tree/dev/crane4j-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("Gitee"),r("OutboundLink")],1),e._v(" / "),r("a",{attrs:{href:"https://github.com/opengoofy/crane4j/tree/dev/crane4j-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("GitHub"),r("OutboundLink")],1),e._v(") 拉到本地运行一下,里面有针对某些比较复杂的功能的集成测试,或许会有助于理解和使用对应功能。")])])}),[],!1,null,null,null);r.default=v.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/8.bf6794dd.js b/docs/assets/js/8.4a9aa5ac.js similarity index 99% rename from docs/assets/js/8.bf6794dd.js rename to docs/assets/js/8.4a9aa5ac.js index 5e0c5bf8..46844da9 100644 --- a/docs/assets/js/8.bf6794dd.js +++ b/docs/assets/js/8.4a9aa5ac.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{274:function(v,s,e){v.exports=e.p+"assets/img/image-20230220191856595.fbd0659c.png"},323:function(v,s,e){"use strict";e.r(s);var _=e(14),a=Object(_.a)({},(function(){var v=this,s=v._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[s("h2",{attrs:{id:"执行流程"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行流程"}},[v._v("#")]),v._v(" 执行流程")]),v._v(" "),s("p",[s("img",{attrs:{src:e(274),alt:"image-20230220191856595"}})]),v._v(" "),s("p",[s("code",[v._v("crane4j")]),v._v(" 的整体执行流程并不复杂,可大致分为两阶段:")]),v._v(" "),s("ul",[s("li",[v._v("配置解析阶段:根据 "),s("code",[v._v("AnnotatedElement")]),v._v(" (一般是类或者方法)解析获得对应的操作配置对象 "),s("code",[v._v("BeanOperation")]),v._v(",通过该配置对象我们可以知道一个对象中有多少个字段需要处理,要怎么处理,在 "),s("code",[v._v("BeanOperation")]),v._v(" 里面,一个 "),s("code",[v._v("key")]),v._v(" 字段对应的一个操作会被转为一个 "),s("code",[v._v("Operation")]),v._v(" 对象;")]),v._v(" "),s("li",[v._v("操作执行阶段:输入要处理的对象,与该对象类型对应操作配置,然后交由操作执行器 "),s("code",[v._v("BeanOperationExecutor")]),v._v(" 生成待完成的任务 "),s("code",[v._v("Execution")]),v._v(",并最终分发给操作执行器 "),s("code",[v._v("OperationHandler")]),v._v(","),s("code",[v._v("OperationHandler")]),v._v(" 会根据配置从数据源获得对象,并完成具体的字段映射;")])]),v._v(" "),s("p",[v._v("比如上图,即描述了 "),s("code",[v._v("Foo")]),v._v(" 对象是如何通过 "),s("code",[v._v("id")]),v._v(" 获得数据源,并将数据源中的 "),s("code",[v._v("userName")]),v._v(" 字段值映射到 "),s("code",[v._v("Foo")]),v._v(" 的 "),s("code",[v._v("name")]),v._v(" 字段上的。")]),v._v(" "),s("h2",{attrs:{id:"操作配置-配置解析器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作配置-配置解析器"}},[v._v("#")]),v._v(" 操作配置 & 配置解析器")]),v._v(" "),s("p",[v._v("在 "),s("code",[v._v("crane4j")]),v._v(" 中,操作是任务的最小单位,它分为两类:")]),v._v(" "),s("ul",[s("li",[s("strong",[v._v("装配操作")]),v._v(" :对应接口为 "),s("code",[v._v("AssembleOperation")]),v._v(",即“把xx塞到xx”这样的行为,“根据 A 的 key 值拿到 B,再把 B 的属性映射到 A” 这句话描述的就是一次装配操作;")]),v._v(" "),s("li",[s("strong",[v._v("拆卸操作")]),v._v(":对应接口为 "),s("code",[v._v("DisassembleOperation")]),v._v(",即“把xx从xx中拿出来”这样的行为,当存在需要处理的嵌套对象时,我们需要先把嵌套对象取出并展开,则就是一次拆卸操作;")])]),v._v(" "),s("p",[v._v("它们有一个共同的特点,就是需要绑定在某个特定属性上,比如装配操作就需要绑定一个外键的字段,而拆卸操作需要绑定装有嵌套对象的字段,它们都称为 "),s("strong",[v._v("key 字段")]),v._v("。")]),v._v(" "),s("p",[v._v("我们的一个对象——通常也对应一个 "),s("code",[v._v("Class")]),v._v(" ——里面往往会有多个 key 字段,比如我有一个 "),s("code",[v._v("Classroom")]),v._v(" 对象:")]),v._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("public")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("class")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Classroom")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("{")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Integer")]),v._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("String")]),v._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Teacher")]),v._v(" teacher"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(">")])]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("}")]),v._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("public")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("class")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("{")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("}")]),v._v("\n")])])]),s("p",[v._v("我们可能只有一个 id,而需要根据 "),s("code",[v._v("id")]),v._v(" 查到并填充它的 "),s("code",[v._v("name")]),v._v("、"),s("code",[v._v("teacher")]),v._v(" 属性,并且还要根据它内部携带的 "),s("code",[v._v("Student")]),v._v(" 的 "),s("code",[v._v("id")]),v._v(" 填充对应的 "),s("code",[v._v("name")]),v._v(" 字段集合,在这种情况下,一个 "),s("code",[v._v("Classroom")]),v._v(" 类将会绑定三个操作:")]),v._v(" "),s("ul",[s("li",[v._v("根据 "),s("code",[v._v("Classroom.id")]),v._v(" 填充 "),s("code",[v._v("Classroom.name")]),v._v(" 的装配操作;")]),v._v(" "),s("li",[v._v("根据 "),s("code",[v._v("Classroom.id")]),v._v(" 填充 "),s("code",[v._v("Classroom.teacher")]),v._v(" 的装配操作;")]),v._v(" "),s("li",[v._v("将 "),s("code",[v._v("Classroom.student")]),v._v(" 展开的拆卸操作;")])]),v._v(" "),s("p",[v._v("为了便于管理,每个 "),s("code",[v._v("Class")]),v._v(" 都会缓存一个操作配置聚合,即"),s("strong",[v._v("类的操作配置")]),v._v(" "),s("code",[v._v("BeanOperations")]),v._v(",里面记录这个类的所有装配操作和拆卸操作,而集中提供读取 "),s("code",[v._v("Class")]),v._v(" 并且生成操作配置的类,就是"),s("strong",[v._v("配置解析器")]),v._v(" "),s("code",[v._v("BeanOperationsParser")]),v._v(",其中每一个配置注解(比如 "),s("code",[v._v("@Assemble")]),v._v(")都会有对应的"),s("strong",[v._v("注解解析器")]),v._v(" "),s("code",[v._v("OperationAnnotationResolver")]),v._v(" 。")]),v._v(" "),s("p",[v._v("而被处理的对象 "),s("code",[v._v("Classroom")]),v._v(" 就是"),s("strong",[v._v("待处理对象")]),v._v(",而从容器中根据 "),s("code",[v._v("id")]),v._v(" 得到的 "),s("code",[v._v("Classroom")]),v._v(" 对象,就是"),s("strong",[v._v("数据源对象")]),v._v("。")]),v._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[v._v("TIP")]),v._v(" "),s("p",[v._v("将操作注解配置在 "),s("code",[v._v("Class")]),v._v(" 以及 "),s("code",[v._v("Field")]),v._v(" 上是最常见的,不过实际上 "),s("code",[v._v("crane4j")]),v._v(" 支持从任何 "),s("code",[v._v("AnnotatedElement")]),v._v(" 上解析注解并生成配置对象,这意味着如果有必要你也可以把配置配置在方法甚至方法参数上,比如执行操作一章中提到的执行者接口。")])]),v._v(" "),s("h2",{attrs:{id:"操作处理器-操作执行器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作处理器-操作执行器"}},[v._v("#")]),v._v(" 操作处理器 & 操作执行器")]),v._v(" "),s("p",[v._v("现在我们通过 "),s("code",[v._v("Class")]),v._v(" 可以得到待执行的装配操作和拆卸操作配置,然而最终还是需要有一个处理器,去真正的根据配置完成对应的属性读写,此即为操作处理器,其中装配操作由"),s("strong",[v._v("装配操作处理器")]),v._v(" "),s("code",[v._v("AssembleOperationHandler")]),v._v(" 完成,而拆卸操作由"),s("strong",[v._v("拆卸操作处理器")]),v._v(" "),s("code",[v._v("DisassembleOperationHandler")]),v._v(" 完成。")]),v._v(" "),s("p",[v._v("不过,因为操作间允许排序,因此有的操作需要先执行,有的操作需要后执行;并且由于拆卸操作的存在,虽然我们要填充的对象都是 A 类型的,但是通过拆卸操作最终可能拆出来一堆其他类型的对象,这些对象也会有拆卸操作,也会有需要排序的装配操作;为了提高效率,数据源相同的操作最好放在一起完成以便减少获取数据源的次数......")]),v._v(" "),s("p",[v._v("总而言之,我们需要有一个组件,可以尽可能高效而清晰的将操作归类分组,并变成一个批量任务,最终再交由对应的操作处理器完成,这个组件就是"),s("strong",[v._v("操作执行器")]),v._v(" "),s("code",[v._v("BeanOperationsExecutor")]),v._v(",而批量任务即为"),s("strong",[v._v("执行对象")]),v._v(" "),s("code",[v._v("AssembleExecution")]),v._v("。")]),v._v(" "),s("h2",{attrs:{id:"数据源容器-属性映射"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据源容器-属性映射"}},[v._v("#")]),v._v(" 数据源容器 & 属性映射")]),v._v(" "),s("p",[v._v("每个装配操作必然具备三个基本要素:")]),v._v(" "),s("ul",[s("li",[s("strong",[v._v("key 字段")]),v._v(":即用于关联填充数据的外键字段;")]),v._v(" "),s("li",[s("strong",[v._v("数据源容器")]),v._v(":即根据 key 字段值用于获取填充数据的组件;")]),v._v(" "),s("li",[s("strong",[v._v("属性映射")]),v._v(":获取到 key 字段值对应的数据源对象后,要把它的哪些属性值塞到自己的哪些属性值里;")])]),v._v(" "),s("p",[v._v("只要操作处理器支持,数据源容器可以接受,则 key 字段的类型可以是常规的 id 值,或者用分隔符拼接成的 id 字符串,甚至是集合。而属性映射也是同理,只要操作处理器支持,填充的对象和数据源对象的类型是个普通的 JavaBean,还是枚举,甚至是 Map 集合或者数组都行。")]),v._v(" "),s("p",[v._v("数据源容器本身也可以是任何实现了 "),s("code",[v._v("Container")]),v._v(" 接口的东西,它可以是一个简陋的 Map 集合,一段可以调用的方法,甚至是固定的常量,能接受输入 key 值并且返回按 key 值分组的数据的东西都可以作为数据源容器。")]),v._v(" "),s("h2",{attrs:{id:"设计原则"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#设计原则"}},[v._v("#")]),v._v(" 设计原则")]),v._v(" "),s("p",[s("code",[v._v("crane4j")]),v._v(" 在设计的时候,遵循两个原则:")]),v._v(" "),s("ul",[s("li",[v._v("对于 api,希望能够尽可能的符合直觉,即用户觉得这样做应该会有这样的效果,那么它就应该是这样的效果;")]),v._v(" "),s("li",[v._v("对于代码,则希望每个类尽可能做到单一职责,然后再通过细粒度组件的复用与组合来实现功能;")])]),v._v(" "),s("p",[v._v("实际上某种程度上来说,后者是前者的基础,因为有了灵活的细粒度组件,所以我们才可以通过多种方式去组合出我们所需要的功能。这种编码风格,提升了代码的可读性、可测性和可扩展性,不过作为代价,"),s("code",[v._v("crane4j")]),v._v(" 实现某个功能可能需要比较多的类来完成,这导致在缺少类似 spring 这类的 IOC 容器时使用起来会比较爪麻,以及更多的对象所带来的一些内存占用,不过相对收获来说还是很划算的。")]),v._v(" "),s("p",[v._v("作者希望用户使用默认的配置能够用的舒心,但是若有必要也能通过最小范的调整适配自己的逻辑,")])])}),[],!1,null,null,null);s.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{274:function(v,s,e){v.exports=e.p+"assets/img/image-20230220191856595.fbd0659c.png"},322:function(v,s,e){"use strict";e.r(s);var _=e(14),a=Object(_.a)({},(function(){var v=this,s=v._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[s("h2",{attrs:{id:"执行流程"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行流程"}},[v._v("#")]),v._v(" 执行流程")]),v._v(" "),s("p",[s("img",{attrs:{src:e(274),alt:"image-20230220191856595"}})]),v._v(" "),s("p",[s("code",[v._v("crane4j")]),v._v(" 的整体执行流程并不复杂,可大致分为两阶段:")]),v._v(" "),s("ul",[s("li",[v._v("配置解析阶段:根据 "),s("code",[v._v("AnnotatedElement")]),v._v(" (一般是类或者方法)解析获得对应的操作配置对象 "),s("code",[v._v("BeanOperation")]),v._v(",通过该配置对象我们可以知道一个对象中有多少个字段需要处理,要怎么处理,在 "),s("code",[v._v("BeanOperation")]),v._v(" 里面,一个 "),s("code",[v._v("key")]),v._v(" 字段对应的一个操作会被转为一个 "),s("code",[v._v("Operation")]),v._v(" 对象;")]),v._v(" "),s("li",[v._v("操作执行阶段:输入要处理的对象,与该对象类型对应操作配置,然后交由操作执行器 "),s("code",[v._v("BeanOperationExecutor")]),v._v(" 生成待完成的任务 "),s("code",[v._v("Execution")]),v._v(",并最终分发给操作执行器 "),s("code",[v._v("OperationHandler")]),v._v(","),s("code",[v._v("OperationHandler")]),v._v(" 会根据配置从数据源获得对象,并完成具体的字段映射;")])]),v._v(" "),s("p",[v._v("比如上图,即描述了 "),s("code",[v._v("Foo")]),v._v(" 对象是如何通过 "),s("code",[v._v("id")]),v._v(" 获得数据源,并将数据源中的 "),s("code",[v._v("userName")]),v._v(" 字段值映射到 "),s("code",[v._v("Foo")]),v._v(" 的 "),s("code",[v._v("name")]),v._v(" 字段上的。")]),v._v(" "),s("h2",{attrs:{id:"操作配置-配置解析器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作配置-配置解析器"}},[v._v("#")]),v._v(" 操作配置 & 配置解析器")]),v._v(" "),s("p",[v._v("在 "),s("code",[v._v("crane4j")]),v._v(" 中,操作是任务的最小单位,它分为两类:")]),v._v(" "),s("ul",[s("li",[s("strong",[v._v("装配操作")]),v._v(" :对应接口为 "),s("code",[v._v("AssembleOperation")]),v._v(",即“把xx塞到xx”这样的行为,“根据 A 的 key 值拿到 B,再把 B 的属性映射到 A” 这句话描述的就是一次装配操作;")]),v._v(" "),s("li",[s("strong",[v._v("拆卸操作")]),v._v(":对应接口为 "),s("code",[v._v("DisassembleOperation")]),v._v(",即“把xx从xx中拿出来”这样的行为,当存在需要处理的嵌套对象时,我们需要先把嵌套对象取出并展开,则就是一次拆卸操作;")])]),v._v(" "),s("p",[v._v("它们有一个共同的特点,就是需要绑定在某个特定属性上,比如装配操作就需要绑定一个外键的字段,而拆卸操作需要绑定装有嵌套对象的字段,它们都称为 "),s("strong",[v._v("key 字段")]),v._v("。")]),v._v(" "),s("p",[v._v("我们的一个对象——通常也对应一个 "),s("code",[v._v("Class")]),v._v(" ——里面往往会有多个 key 字段,比如我有一个 "),s("code",[v._v("Classroom")]),v._v(" 对象:")]),v._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("public")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("class")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Classroom")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("{")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Integer")]),v._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("String")]),v._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Teacher")]),v._v(" teacher"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(">")])]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("}")]),v._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("public")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("class")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[v._v("Student")]),v._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("{")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[v._v("private")]),v._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v(";")]),v._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("}")]),v._v("\n")])])]),s("p",[v._v("我们可能只有一个 id,而需要根据 "),s("code",[v._v("id")]),v._v(" 查到并填充它的 "),s("code",[v._v("name")]),v._v("、"),s("code",[v._v("teacher")]),v._v(" 属性,并且还要根据它内部携带的 "),s("code",[v._v("Student")]),v._v(" 的 "),s("code",[v._v("id")]),v._v(" 填充对应的 "),s("code",[v._v("name")]),v._v(" 字段集合,在这种情况下,一个 "),s("code",[v._v("Classroom")]),v._v(" 类将会绑定三个操作:")]),v._v(" "),s("ul",[s("li",[v._v("根据 "),s("code",[v._v("Classroom.id")]),v._v(" 填充 "),s("code",[v._v("Classroom.name")]),v._v(" 的装配操作;")]),v._v(" "),s("li",[v._v("根据 "),s("code",[v._v("Classroom.id")]),v._v(" 填充 "),s("code",[v._v("Classroom.teacher")]),v._v(" 的装配操作;")]),v._v(" "),s("li",[v._v("将 "),s("code",[v._v("Classroom.student")]),v._v(" 展开的拆卸操作;")])]),v._v(" "),s("p",[v._v("为了便于管理,每个 "),s("code",[v._v("Class")]),v._v(" 都会缓存一个操作配置聚合,即"),s("strong",[v._v("类的操作配置")]),v._v(" "),s("code",[v._v("BeanOperations")]),v._v(",里面记录这个类的所有装配操作和拆卸操作,而集中提供读取 "),s("code",[v._v("Class")]),v._v(" 并且生成操作配置的类,就是"),s("strong",[v._v("配置解析器")]),v._v(" "),s("code",[v._v("BeanOperationsParser")]),v._v(",其中每一个配置注解(比如 "),s("code",[v._v("@Assemble")]),v._v(")都会有对应的"),s("strong",[v._v("注解解析器")]),v._v(" "),s("code",[v._v("OperationAnnotationResolver")]),v._v(" 。")]),v._v(" "),s("p",[v._v("而被处理的对象 "),s("code",[v._v("Classroom")]),v._v(" 就是"),s("strong",[v._v("待处理对象")]),v._v(",而从容器中根据 "),s("code",[v._v("id")]),v._v(" 得到的 "),s("code",[v._v("Classroom")]),v._v(" 对象,就是"),s("strong",[v._v("数据源对象")]),v._v("。")]),v._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[v._v("TIP")]),v._v(" "),s("p",[v._v("将操作注解配置在 "),s("code",[v._v("Class")]),v._v(" 以及 "),s("code",[v._v("Field")]),v._v(" 上是最常见的,不过实际上 "),s("code",[v._v("crane4j")]),v._v(" 支持从任何 "),s("code",[v._v("AnnotatedElement")]),v._v(" 上解析注解并生成配置对象,这意味着如果有必要你也可以把配置配置在方法甚至方法参数上,比如执行操作一章中提到的执行者接口。")])]),v._v(" "),s("h2",{attrs:{id:"操作处理器-操作执行器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作处理器-操作执行器"}},[v._v("#")]),v._v(" 操作处理器 & 操作执行器")]),v._v(" "),s("p",[v._v("现在我们通过 "),s("code",[v._v("Class")]),v._v(" 可以得到待执行的装配操作和拆卸操作配置,然而最终还是需要有一个处理器,去真正的根据配置完成对应的属性读写,此即为操作处理器,其中装配操作由"),s("strong",[v._v("装配操作处理器")]),v._v(" "),s("code",[v._v("AssembleOperationHandler")]),v._v(" 完成,而拆卸操作由"),s("strong",[v._v("拆卸操作处理器")]),v._v(" "),s("code",[v._v("DisassembleOperationHandler")]),v._v(" 完成。")]),v._v(" "),s("p",[v._v("不过,因为操作间允许排序,因此有的操作需要先执行,有的操作需要后执行;并且由于拆卸操作的存在,虽然我们要填充的对象都是 A 类型的,但是通过拆卸操作最终可能拆出来一堆其他类型的对象,这些对象也会有拆卸操作,也会有需要排序的装配操作;为了提高效率,数据源相同的操作最好放在一起完成以便减少获取数据源的次数......")]),v._v(" "),s("p",[v._v("总而言之,我们需要有一个组件,可以尽可能高效而清晰的将操作归类分组,并变成一个批量任务,最终再交由对应的操作处理器完成,这个组件就是"),s("strong",[v._v("操作执行器")]),v._v(" "),s("code",[v._v("BeanOperationsExecutor")]),v._v(",而批量任务即为"),s("strong",[v._v("执行对象")]),v._v(" "),s("code",[v._v("AssembleExecution")]),v._v("。")]),v._v(" "),s("h2",{attrs:{id:"数据源容器-属性映射"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据源容器-属性映射"}},[v._v("#")]),v._v(" 数据源容器 & 属性映射")]),v._v(" "),s("p",[v._v("每个装配操作必然具备三个基本要素:")]),v._v(" "),s("ul",[s("li",[s("strong",[v._v("key 字段")]),v._v(":即用于关联填充数据的外键字段;")]),v._v(" "),s("li",[s("strong",[v._v("数据源容器")]),v._v(":即根据 key 字段值用于获取填充数据的组件;")]),v._v(" "),s("li",[s("strong",[v._v("属性映射")]),v._v(":获取到 key 字段值对应的数据源对象后,要把它的哪些属性值塞到自己的哪些属性值里;")])]),v._v(" "),s("p",[v._v("只要操作处理器支持,数据源容器可以接受,则 key 字段的类型可以是常规的 id 值,或者用分隔符拼接成的 id 字符串,甚至是集合。而属性映射也是同理,只要操作处理器支持,填充的对象和数据源对象的类型是个普通的 JavaBean,还是枚举,甚至是 Map 集合或者数组都行。")]),v._v(" "),s("p",[v._v("数据源容器本身也可以是任何实现了 "),s("code",[v._v("Container")]),v._v(" 接口的东西,它可以是一个简陋的 Map 集合,一段可以调用的方法,甚至是固定的常量,能接受输入 key 值并且返回按 key 值分组的数据的东西都可以作为数据源容器。")]),v._v(" "),s("h2",{attrs:{id:"设计原则"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#设计原则"}},[v._v("#")]),v._v(" 设计原则")]),v._v(" "),s("p",[s("code",[v._v("crane4j")]),v._v(" 在设计的时候,遵循两个原则:")]),v._v(" "),s("ul",[s("li",[v._v("对于 api,希望能够尽可能的符合直觉,即用户觉得这样做应该会有这样的效果,那么它就应该是这样的效果;")]),v._v(" "),s("li",[v._v("对于代码,则希望每个类尽可能做到单一职责,然后再通过细粒度组件的复用与组合来实现功能;")])]),v._v(" "),s("p",[v._v("实际上某种程度上来说,后者是前者的基础,因为有了灵活的细粒度组件,所以我们才可以通过多种方式去组合出我们所需要的功能。这种编码风格,提升了代码的可读性、可测性和可扩展性,不过作为代价,"),s("code",[v._v("crane4j")]),v._v(" 实现某个功能可能需要比较多的类来完成,这导致在缺少类似 spring 这类的 IOC 容器时使用起来会比较爪麻,以及更多的对象所带来的一些内存占用,不过相对收获来说还是很划算的。")]),v._v(" "),s("p",[v._v("作者希望用户使用默认的配置能够用的舒心,但是若有必要也能通过最小范的调整适配自己的逻辑,")])])}),[],!1,null,null,null);s.default=a.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/app.eab2957f.js b/docs/assets/js/app.04c8fb5b.js similarity index 79% rename from docs/assets/js/app.eab2957f.js rename to docs/assets/js/app.04c8fb5b.js index 9197154b..2791fcf2 100644 --- a/docs/assets/js/app.eab2957f.js +++ b/docs/assets/js/app.04c8fb5b.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var r,a,s=e[0],c=e[1],l=e[2],f=0,p=[];f
'};function o(t,e,n){return tn?n:t}function i(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(r[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=o(t,r.minimum,1),n.status=1===t?null:t;var c=n.render(!e),l=c.querySelector(r.barSelector),u=r.speed,f=r.easing;return c.offsetWidth,a((function(e){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(l,function(t,e,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(t)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(t)+"%,0)"}:{"margin-left":i(t)+"%"}).transition="all "+e+"ms "+n,o}(t,u,f)),1===t?(s(c,{transition:"none",opacity:1}),c.offsetWidth,setTimeout((function(){s(c,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),e()}),u)}),u)):setTimeout(e,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var t=function(){setTimeout((function(){n.status&&(n.trickle(),t())}),r.trickleSpeed)};return r.trickle&&t(),this},n.done=function(t){return t||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(t){var e=n.status;return e?("number"!=typeof t&&(t=(1-e)*o(Math.random()*e,.1,.95)),e=o(e+t,0,.994),n.set(e)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},t=0,e=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===e&&n.start(),t++,e++,r.always((function(){0==--e?(t=0,n.done()):n.set((t-e)/t)})),this):this},n.render=function(t){if(n.isRendered())return document.getElementById("nprogress");l(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=r.template;var o,a=e.querySelector(r.barSelector),c=t?"-100":i(n.status||0),u=document.querySelector(r.parent);return s(a,{transition:"all 0 linear",transform:"translate3d("+c+"%,0,0)"}),r.showSpinner||(o=e.querySelector(r.spinnerSelector))&&p(o),u!=document.body&&l(u,"nprogress-custom-parent"),u.appendChild(e),e},n.remove=function(){u(document.documentElement,"nprogress-busy"),u(document.querySelector(r.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&p(t)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var a=function(){var t=[];function e(){var n=t.shift();n&&n(e)}return function(n){t.push(n),1==t.length&&e()}}(),s=function(){var t=["Webkit","O","Moz","ms"],e={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(t,e){return e.toUpperCase()})),e[n]||(e[n]=function(e){var n=document.body.style;if(e in n)return e;for(var r,o=t.length,i=e.charAt(0).toUpperCase()+e.slice(1);o--;)if((r=t[o]+i)in n)return r;return e}(n))}function r(t,e,r){e=n(e),t.style[e]=r}return function(t,e){var n,o,i=arguments;if(2==i.length)for(n in e)void 0!==(o=e[n])&&e.hasOwnProperty(n)&&r(t,n,o);else r(t,i[1],i[2])}}();function c(t,e){return("string"==typeof t?t:f(t)).indexOf(" "+e+" ")>=0}function l(t,e){var n=f(t),r=n+e;c(n,e)||(t.className=r.substring(1))}function u(t,e){var n,r=f(t);c(t,e)&&(n=r.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function f(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function p(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?r.call(e,n,e,t):r)||(t.exports=o)},function(t,e,n){var r=n(3),o=n(45).f,i=n(12),a=n(103),s=n(32),c=n(61),l=n(119);t.exports=function(t,e){var n,u,f,p,h,d=t.target,v=t.global,m=t.stat;if(n=v?r:m?r[d]||s(d,{}):(r[d]||{}).prototype)for(u in e){if(p=e[u],f=t.dontCallGetSet?(h=o(n,u))&&h.value:n[u],!l(v?u:d+(m?".":"#")+u,t.forced)&&void 0!==f){if(typeof p==typeof f)continue;c(p,f)}(t.sham||f&&f.sham)&&i(p,"sham",!0),a(n,u,p,t)}}},function(t,e,n){var r=n(25),o=Function.prototype.call;t.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},function(t,e,n){var r=n(1);t.exports=!r((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var r=n(46),o=n(47);t.exports=function(t){return r(o(t))}},function(t,e,n){var r=n(3),o=n(0),i=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?i(r[t]):r[t]&&r[t][e]}},function(t,e,n){var r=n(0),o=n(99),i=TypeError;t.exports=function(t){if(r(t))return t;throw i(o(t)+" is not a function")}},function(t,e,n){var r=n(3),o=n(56),i=n(7),a=n(58),s=n(54),c=n(53),l=r.Symbol,u=o("wks"),f=c?l.for||l:l&&l.withoutSetter||a;t.exports=function(t){return i(u,t)||(u[t]=s&&i(l,t)?l[t]:f("Symbol."+t)),u[t]}},function(t,e,n){var r=n(3),o=n(32),i=r["__core-js_shared__"]||o("__core-js_shared__",{});t.exports=i},function(t,e,n){var r=n(3),o=Object.defineProperty;t.exports=function(t,e){try{o(r,t,{value:e,configurable:!0,writable:!0})}catch(n){r[t]=e}return e}},function(t,e,n){var r=n(47),o=Object;t.exports=function(t){return o(r(t))}},function(t,e,n){var r=n(8),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw i(o(t)+" is not an object")}},function(t,e,n){var r=n(116);t.exports=function(t){return r(t.length)}},function(t,e,n){var r=n(143),o=n(10),i=Object.prototype,a=i.hasOwnProperty,s=i.propertyIsEnumerable,c=r(function(){return arguments}())?r:function(t){return o(t)&&a.call(t,"callee")&&!s.call(t,"callee")};t.exports=c},function(t,e,n){var r=n(9)(n(6),"Map");t.exports=r},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,n){var r=n(163),o=n(170),i=n(172),a=n(173),s=n(174);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){var r=n(4),o=n(43),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(r(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!o(t))||(a.test(t)||!i.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var r=n(11),o=n(10);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==r(t)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){var r=n(5),o=n(24),i=n(95),a=n(26),s=n(27),c=n(49),l=n(7),u=n(59),f=Object.getOwnPropertyDescriptor;e.f=r?f:function(t,e){if(t=s(t),e=c(e),u)try{return f(t,e)}catch(t){}if(l(t,e))return a(!o(i.f,t,e),t[e])}},function(t,e,n){var r=n(2),o=n(1),i=n(15),a=Object,s=r("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"==i(t)?s(t,""):a(t)}:a},function(t,e,n){var r=n(48),o=TypeError;t.exports=function(t){if(r(t))throw o("Can't call method on "+t);return t}},function(t,e){t.exports=function(t){return null==t}},function(t,e,n){var r=n(96),o=n(51);t.exports=function(t){var e=r(t,"string");return o(e)?e:e+""}},function(t,e){var n="object"==typeof document&&document.all,r=void 0===n&&void 0!==n;t.exports={all:n,IS_HTMLDDA:r}},function(t,e,n){var r=n(28),o=n(0),i=n(52),a=n(53),s=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=r("Symbol");return o(e)&&i(e.prototype,s(t))}},function(t,e,n){var r=n(2);t.exports=r({}.isPrototypeOf)},function(t,e,n){var r=n(54);t.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){var r=n(55),o=n(1);t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol();return!String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},function(t,e,n){var r,o,i=n(3),a=n(97),s=i.process,c=i.Deno,l=s&&s.versions||c&&c.version,u=l&&l.v8;u&&(o=(r=u.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(o=+r[1]),t.exports=o},function(t,e,n){var r=n(57),o=n(31);(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.28.0",mode:r?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.28.0/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e){t.exports=!1},function(t,e,n){var r=n(2),o=0,i=Math.random(),a=r(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++o+i,36)}},function(t,e,n){var r=n(5),o=n(1),i=n(101);t.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e){t.exports={}},function(t,e,n){var r=n(7),o=n(110),i=n(45),a=n(16);t.exports=function(t,e,n){for(var s=o(e),c=a.f,l=i.f,u=0;uu))return!1;var p=c.get(t),h=c.get(e);if(p&&h)return p==e&&h==t;var d=-1,v=!0,m=2&n?new r:void 0;for(c.set(t,e),c.set(e,t);++d-1&&t%1==0&&t=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||p(t)&&t.toString===f?JSON.stringify(t,null,2):String(t)}function E(t){var e=parseFloat(t);return isNaN(e)?t:e}function g(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var _=Object.prototype.hasOwnProperty;function A(t,e){return _.call(t,e)}function B(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,w=B((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),C=B((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),k=/\B([A-Z])/g,O=B((function(t){return t.replace(k,"-$1").toLowerCase()}));var $=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function j(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function S(t,e){for(var n in e)t[n]=e[n];return t}function D(t){for(var e={},n=0;n0,Q=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var Z=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var tt,et=J&&J.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(G)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function st(t){return"function"==typeof t&&/native code/.test(t.toString())}var ct,lt="undefined"!=typeof Symbol&&st(Symbol)&&"undefined"!=typeof Reflect&&st(Reflect.ownKeys);ct="undefined"!=typeof Set&&st(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var ut=null;function ft(t){void 0===t&&(t=null),t||ut&&ut._scope.off(),ut=t,t&&t._scope.on()}var pt=function(){function t(t,e,n,r,o,i,a,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ht=function(t){void 0===t&&(t="");var e=new pt;return e.text=t,e.isComment=!0,e};function dt(t){return new pt(void 0,void 0,void 0,String(t))}function vt(t){var e=new pt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,Et=[],gt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,Et.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,r=e.length;n0&&(Jt((l=t(l,"".concat(n||"","_").concat(r)))[0])&&Jt(f)&&(p[u]=dt(f.text+l[0].text),l.shift()),p.push.apply(p,l)):c(l)?Jt(f)?p[u]=dt(f.text+l):""!==l&&p.push(dt(l)):Jt(l)&&Jt(f)?p[u]=dt(f.text+l.text):(s(e._isVList)&&a(l.tag)&&i(l.key)&&a(n)&&(l.key="__vlist".concat(n,"_").concat(r,"__")),p.push(l)));return p}(t):void 0}function Jt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,r,i,s,c=null;if(o(t)||"string"==typeof t)for(c=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!a,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&o&&o!==r&&c===o.$key&&!a&&!o.$hasNormal)return o;for(var l in i={},e)e[l]&&"$"!==l[0]&&(i[l]=ve(t,n,l,e[l]))}else i={};for(var u in n)u in i||(i[u]=me(n,u));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",s),H(i,"$key",c),H(i,"$hasNormal",a),i}function ve(t,e,n,r){var i=function(){var e=ut;ft(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Gt(n))&&n[0];return ft(e),n&&(!i||1===n.length&&i.isComment&&!he(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function me(t,e){return function(){return t[e]}}function Ee(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ge(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ge(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||be(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:$(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return It(t,e,n)}))}}}function ge(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,ye(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function ye(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function be(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var _e=null;function Ae(t,e){return(t.__esModule||lt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),u(t)?e.extend(t):t}function Be(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(cn=function(){return ln.now()})}var un=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function fn(){var t,e;for(sn=cn(),on=!0,tn.sort(un),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Me(fn))}}function hn(t,e){if(t){for(var n=Object.create(null),r=lt?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!A(o,"default"))a=!1;else if(""===a||a===O(t)){var c=Ln(String,o.type);(c<0||s-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!h(t)&&t.test(e)}function Xn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Yn(n,i,r,o)}}}function Yn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,b(n,e)}Wn.prototype._init=function(t){var e=this;e._uid=Vn++,e._isVue=!0,e.__v_skip=!0,e._scope=new qt(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=$n(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ge(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=fe(e._renderChildren,o),t.$scopedSlots=n?de(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return xe(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return xe(t,e,n,r,o,!0)};var i=n&&n.data;St(t,"$attrs",i&&i.attrs||r,null,!0),St(t,"$listeners",e._parentListeners||r,null,!0)}(e),Ze(e,"beforeCreate",void 0,!1),function(t){var e=hn(t.$options.inject,t);e&&(kt(!1),Object.keys(e).forEach((function(n){St(t,n,e[n])})),kt(!0))}(e),Mn(e),function(t){var e=t.$options.provide;if(e){var n=l(e)?e.call(t):e;if(!u(n))return;for(var r=Ut(t),o=lt?Reflect.ownKeys(n):Object.keys(n),i=0;i1?j(n):n;for(var r=j(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Yn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Jn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Jn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Be(t),n=e&&e.componentOptions;if(n){var r=Gn(n),o=this.include,i=this.exclude;if(o&&(!r||!Jn(o,r))||i&&r&&Jn(i,r))return e;var a=this.cache,s=this.keys,c=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[c]?(e.componentInstance=a[c].componentInstance,b(s,c),s.push(c)):(this.vnodeToCache=e,this.keyToCache=c),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return U}};Object.defineProperty(t,"config",e),t.util={warn:An,extend:S,mergeOptions:$n,defineReactive:St},t.set=Dt,t.delete=Pt,t.nextTick=Me,t.observable=function(t){return jt(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,S(t.options.components,Zn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=j(arguments,1);return n.unshift(this),l(t.install)?t.install.apply(t,n):l(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=$n(this.options,t),this}}(t),Kn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&p(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&l(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:it}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:dn}),Wn.version="2.7.14";var tr=g("style,class"),er=g("input,textarea,option,select,progress"),nr=g("contenteditable,draggable,spellcheck"),rr=g("events,caret,typing,plaintext-only"),or=g("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},sr=function(t){return ar(t)?t.slice(6,t.length):""},cr=function(t){return null==t||!1===t};function lr(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=ur(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=ur(e,n.data));return function(t,e){if(a(t)||a(e))return fr(t,pr(e));return""}(e.staticClass,e.class)}function ur(t,e){return{staticClass:fr(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function fr(t,e){return t?e?t+" "+e:t:e||""}function pr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?Fr(t,e,n):or(e)?cr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return cr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?cr(n)?t.removeAttributeNS(ir,sr(e)):t.setAttributeNS(ir,e,n):Fr(t,e,n)}function Fr(t,e,n){if(cr(n))t.removeAttribute(e);else{if(X&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Rr={create:Tr,update:Tr};function Mr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var s=lr(e),c=n._transitionClasses;a(c)&&(s=fr(s,pr(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var Ir,Nr={create:Mr,update:Mr};function qr(t,e,n){var r=Ir;return function o(){var i=e.apply(null,arguments);null!==i&&Vr(t,o,n,r)}}var Ur=je&&!(et&&Number(et[1])<=53);function zr(t,e,n,r){if(Ur){var o=sn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ir.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Vr(t,e,n,r){(r||Ir).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Ir=e.elm||t.elm,function(t){if(a(t.__r)){var e=X?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,r,zr,Vr,qr,e.context),Ir=void 0}}var Wr,Kr={create:Hr,update:Hr,destroy:function(t){return Hr(t,Br)}};function Gr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,o=e.elm,c=t.data.domProps||{},l=e.data.domProps||{};for(n in(a(l.__ob__)||s(l._v_attr_proxy))&&(l=e.data.domProps=S({},l)),c)n in l||(o[n]="");for(n in l){if(r=l[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===c[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var u=i(r)?"":String(r);Jr(o,u)&&(o.value=u)}else if("innerHTML"===n&&vr(o.tagName)&&i(o.innerHTML)){(Wr=Wr||document.createElement("div")).innerHTML="".concat(r,"");for(var f=Wr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;f.firstChild;)o.appendChild(f.firstChild)}else if(r!==c[n])try{o[n]=r}catch(t){}}}}function Jr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(a(r)){if(r.number)return E(n)!==E(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xr={create:Gr,update:Gr},Yr=B((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Qr(t){var e=Zr(t.style);return t.staticStyle?S(t.staticStyle,e):e}function Zr(t){return Array.isArray(t)?D(t):"string"==typeof t?Yr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(O(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(co).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function uo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(co).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function fo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&S(e,po(t.name||"v")),S(e,t),e}return"string"==typeof t?po(t):void 0}}var po=B((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ho=G&&!Y,vo="transition",mo="transitionend",Eo="animation",go="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(vo="WebkitTransition",mo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Eo="WebkitAnimation",go="webkitAnimationEnd"));var yo=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function bo(t){yo((function(){yo(t)}))}function _o(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),lo(t,e))}function Ao(t,e){t._transitionClasses&&b(t._transitionClasses,e),uo(t,e)}function Bo(t,e,n){var r=wo(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s="transition"===o?mo:go,c=0,l=function(){t.removeEventListener(s,u),n()},u=function(e){e.target===t&&++c>=a&&l()};setTimeout((function(){c0&&(n="transition",u=a,f=i.length):"animation"===e?l>0&&(n="animation",u=l,f=c.length):f=(n=(u=Math.max(a,l))>0?a>l?"transition":"animation":null)?"transition"===n?i.length:c.length:0,{type:n,timeout:u,propCount:f,hasTransform:"transition"===n&&xo.test(r[vo+"Property"])}}function Co(t,e){for(;t.length1}function Do(t,e){!0!==e.data.show&&Oo(e)}var Po=function(t){var e,n,r={},l=t.modules,u=t.nodeOps;for(e=0;ed?b(t,i(n[E+1])?null:n[E+1].elm,n,h,E,r):h>E&&A(e,f,d)}(f,v,E,n,l):a(E)?(a(t.text)&&u.setTextContent(f,""),b(f,null,E,0,E.length-1,n)):a(v)?A(v,0,v.length-1):a(t.text)&&u.setTextContent(f,""):t.text!==e.text&&u.setTextContent(f,e.text),a(d)&&a(h=d.hook)&&a(h=h.postpatch)&&h(t,e)}}}function C(t,e,n){if(s(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(F(Mo(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Ro(t,e){return e.every((function(e){return!F(e,t)}))}function Mo(t){return"_value"in t?t._value:t.value}function Io(t){t.target.composing=!0}function No(t){t.target.composing&&(t.target.composing=!1,qo(t.target,"input"))}function qo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Uo(t){return!t.componentInstance||t.data&&t.data.transition?t:Uo(t.componentInstance._vnode)}var zo={model:To,show:{bind:function(t,e,n){var r=e.value,o=(n=Uo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,Oo(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=Uo(n)).data&&n.data.transition?(n.data.show=!0,r?Oo(n,(function(){t.style.display=t.__vOriginalDisplay})):$o(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Vo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(Be(e.children)):t}function Wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[w(r)]=o[r];return e}function Ko(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Go=function(t){return t.tag||he(t)},Jo=function(t){return"show"===t.name},Xo={name:"transition",props:Vo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Go)).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=Ho(o);if(!i)return o;if(this._leaving)return Ko(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=Wo(this),l=this._vnode,u=Ho(l);if(i.data.directives&&i.data.directives.some(Jo)&&(i.data.show=!0),u&&u.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,u)&&!he(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var f=u.data.transition=S({},s);if("out-in"===r)return this._leaving=!0,Wt(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Ko(t,o);if("in-out"===r){if(he(i))return l;var p,h=function(){p()};Wt(s,"afterEnter",h),Wt(s,"enterCancelled",h),Wt(f,"delayLeave",(function(t){p=t}))}}return o}}},Yo=S({tag:String,moveClass:String},Vo);function Qo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Zo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Yo.mode;var ei={Transition:Xo,TransitionGroup:{props:Yo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Wo(this),s=0;s-1?Er[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Er[t]=/HTMLUnknownElement/.test(e.toString())},S(Wn.options.directives,zo),S(Wn.options.components,ei),Wn.prototype.__patch__=G?Po:P,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=ht),Ze(t,"beforeMount"),r=function(){t._update(t._render(),n)},new Ve(t,r,P,{before:function(){t._isMounted&&!t._isDestroyed&&Ze(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),l=e&&e.path||"/",u=c.path?Ai(c.path,l,n||o.append):l,f=function(t,e,n){void 0===e&&(e={});var r,o=n||li;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(ci):ci(a)}return r}(c.query,o.query,r&&r.options.parseQuery),p=o.hash||c.hash;return p&&"#"!==p.charAt(0)&&(p="#"+p),{_normalized:!0,path:u,query:f,hash:p}}var zi,Vi=function(){},Hi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,s=o.href,c={},l=n.options.linkActiveClass,u=n.options.linkExactActiveClass,f=null==l?"router-link-active":l,p=null==u?"router-link-exact-active":u,h=null==this.activeClass?f:this.activeClass,d=null==this.exactActiveClass?p:this.exactActiveClass,v=a.redirectedFrom?pi(null,Ui(a.redirectedFrom),null,n):a;c[d]=Ei(r,v,this.exactPath),c[h]=this.exact||this.exactPath?c[d]:function(t,e){return 0===t.path.replace(fi,"/").indexOf(e.path.replace(fi,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,v);var m=c[d]?this.ariaCurrentValue:null,E=function(t){Wi(t)&&(e.replace?n.replace(i,Vi):n.push(i,Vi))},g={click:Wi};Array.isArray(this.event)?this.event.forEach((function(t){g[t]=E})):g[this.event]=E;var y={class:c},b=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:s,route:a,navigate:E,isActive:c[h],isExactActive:c[d]});if(b){if(1===b.length)return b[0];if(b.length>1||!b.length)return 0===b.length?t():t("span",{},b)}if("a"===this.tag)y.on=g,y.attrs={href:s,"aria-current":m};else{var _=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=qi(u.path,s.params),c(u,s,a)}if(s.path){s.params={};for(var h=0;h-1}function Ba(t,e){return Aa(t)&&t._isRouter&&(null==e||t.type===e)}function xa(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function wa(t){return function(e,n,r){var o=!1,i=0,a=null;Ca(t,(function(t,e,n,s){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var c,l=$a((function(e){var o;((o=e).__esModule||Oa&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zi.extend(e),n.components[s]=e,--i<=0&&r()})),u=$a((function(t){var e="Failed to resolve async component "+s+": "+t;a||(a=Aa(t)?t:new Error(e),r(a))}));try{c=t(l,u)}catch(t){u(t)}if(c)if("function"==typeof c.then)c.then(l,u);else{var f=c.component;f&&"function"==typeof f.then&&f.then(l,u)}}})),o||r()}}function Ca(t,e){return ka(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function ka(t){return Array.prototype.concat.apply([],t)}var Oa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function $a(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var ja=function(t,e){this.router=t,this.base=function(t){if(!t)if(Ki){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=di,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Sa(t,e,n,r){var o=Ca(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=zi.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return ka(r?o.reverse():o)}function Da(t,e){if(e)return function(){return t.apply(e,arguments)}}ja.prototype.listen=function(t){this.cb=t},ja.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},ja.prototype.onError=function(t){this.errorCbs.push(t)},ja.prototype.transitionTo=function(t,e,n){var r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(Ba(t,Ea.redirected)&&i===di||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},ja.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,s=function(t){!Ba(t)&&Aa(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},c=t.matched.length-1,l=o.matched.length-1;if(Ei(t,o)&&c===l&&t.matched[c]===o.matched[l])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),s(((a=ba(i=o,t,Ea.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var u=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=da&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Ta(t.base);t.current===di&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){va(Bi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){ma(Bi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ta(this.base)!==this.current.fullPath){var e=Bi(this.base+this.current.fullPath);t?va(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ta(this.base)},e}(ja);function Ta(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(Bi(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var La=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Ta(t);if(!/^\/#/.test(e))return window.location.replace(Bi(t+"/#"+e)),!0}(this.base)||Fa()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=da&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;Fa()&&t.transitionTo(Ra(),(function(r){n&&ia(t.router,r,e,!0),da||Na(r.fullPath)}))},o=da?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Ia(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ra()!==e&&(t?Ia(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ra()},e}(ja);function Fa(){var t=Ra();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ra(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ma(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ia(t){da?va(Ma(t)):window.location.hash=t}function Na(t){da?ma(Ma(t)):window.location.replace(Ma(t))}var qa=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){Ba(t,Ea.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(ja),Ua=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xi(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!da&&!1!==t.fallback,this.fallback&&(e="hash"),Ki||(e="abstract"),this.mode=e,e){case"history":this.history=new Pa(this,t.base);break;case"hash":this.history=new La(this,t.base,this.fallback);break;case"abstract":this.history=new qa(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Ua.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Ua.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Pa||n instanceof La){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;da&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ua.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Ua.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Ua.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Ua.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ua.prototype.onError=function(t){this.history.onError(t)},Ua.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Ua.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ua.prototype.go=function(t){this.history.go(t)},Ua.prototype.back=function(){this.go(-1)},Ua.prototype.forward=function(){this.go(1)},Ua.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ua.prototype.resolve=function(t,e,n){var r=Ui(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?Bi(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Ua.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ua.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==di&&this.history.transitionTo(this.history.getCurrentLocation())},Ua.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==di&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ua.prototype,za);var Va=Ua;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ua.install=function t(e){if(!t.installed||zi!==e){t.installed=!0,zi=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",bi),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Ua.version="3.6.5",Ua.isNavigationFailure=Ba,Ua.NavigationFailureType=Ea,Ua.START_LOCATION=di,Ki&&window.Vue&&window.Vue.use(Ua);n(94);n(90),n(126);var Wa={NotFound:()=>n.e(9).then(n.bind(null,281)),Layout:()=>Promise.all([n.e(0),n.e(2)]).then(n.bind(null,280))},Ka={"v-1151045e":()=>n.e(10).then(n.bind(null,284)),"v-7687dbe3":()=>n.e(12).then(n.bind(null,285)),"v-3b4a094a":()=>n.e(15).then(n.bind(null,286)),"v-7ade593d":()=>n.e(13).then(n.bind(null,287)),"v-206a88f7":()=>n.e(14).then(n.bind(null,288)),"v-06e226fd":()=>n.e(11).then(n.bind(null,289)),"v-49ed32b8":()=>n.e(18).then(n.bind(null,290)),"v-6c043199":()=>n.e(16).then(n.bind(null,291)),"v-a2e60fe0":()=>n.e(19).then(n.bind(null,292)),"v-700b7892":()=>n.e(23).then(n.bind(null,293)),"v-51ee3d19":()=>n.e(21).then(n.bind(null,294)),"v-97ff7a9a":()=>n.e(24).then(n.bind(null,295)),"v-b799f18e":()=>n.e(22).then(n.bind(null,296)),"v-7e84bb17":()=>n.e(25).then(n.bind(null,297)),"v-b48601fc":()=>n.e(26).then(n.bind(null,298)),"v-5d96c30f":()=>n.e(20).then(n.bind(null,299)),"v-afd7a946":()=>n.e(29).then(n.bind(null,300)),"v-6d10ef40":()=>n.e(27).then(n.bind(null,301)),"v-4642376c":()=>n.e(31).then(n.bind(null,302)),"v-1d6c8203":()=>n.e(28).then(n.bind(null,303)),"v-6aee24e3":()=>n.e(30).then(n.bind(null,304)),"v-a7970784":()=>n.e(32).then(n.bind(null,305)),"v-c0e295c2":()=>n.e(7).then(n.bind(null,306)),"v-07d72cc6":()=>n.e(17).then(n.bind(null,307)),"v-14f016fd":()=>n.e(34).then(n.bind(null,308)),"v-1fb25314":()=>n.e(37).then(n.bind(null,309)),"v-19857dfe":()=>n.e(36).then(n.bind(null,310)),"v-4c42f052":()=>n.e(38).then(n.bind(null,311)),"v-74c62ac8":()=>n.e(39).then(n.bind(null,312)),"v-54898c6d":()=>n.e(40).then(n.bind(null,313)),"v-9c39d86e":()=>n.e(33).then(n.bind(null,314)),"v-4d08fff8":()=>n.e(35).then(n.bind(null,315)),"v-995c65a0":()=>n.e(43).then(n.bind(null,316)),"v-031526f1":()=>n.e(42).then(n.bind(null,317)),"v-0b603d28":()=>n.e(45).then(n.bind(null,318)),"v-2c4163e0":()=>n.e(41).then(n.bind(null,319)),"v-644d0f52":()=>n.e(47).then(n.bind(null,320)),"v-19618f9e":()=>n.e(44).then(n.bind(null,321)),"v-915ccd2a":()=>n.e(46).then(n.bind(null,322)),"v-3289f112":()=>n.e(8).then(n.bind(null,323)),"v-b7c30ce4":()=>n.e(6).then(n.bind(null,324))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Ja=/-(\w)/g,Xa=Ga(t=>t.replace(Ja,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Qa=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Za=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function ts(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Za(Xa(e))):t(Za(e))||t(Qa(e))}const es=Object.assign({},Wa,Ka),ns=t=>es[t],rs=t=>Ka[t],os=t=>Wa[t],is=t=>Wn.component(t);function as(t){return ts(rs,t)}function ss(t){return ts(os,t)}function cs(t){return ts(ns,t)}function ls(t){return ts(is,t)}function us(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!ls(t)&&cs(t)){const e=await cs(t)();Wn.component(t,e.default)}}))}function fs(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var ps=n(87),hs=n.n(ps),ds=n(88),vs=n.n(ds),ms={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${vs()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=gs(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=ys(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return hs()([{name:"description",content:this.$description}],t,this.siteMeta,bs)},updateCanonicalLink(){Es(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",gs(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){ys(null,this.currentMetaTags),Es()}};function Es(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function gs(t=""){return t?``:""}function ys(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function bs(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var _s=n(89),As={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(_s)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Bs=n(22),xs=n.n(Bs),ws=[ms,As,{mounted(){xs.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Wn.component(t.name)||xs.a.start(),n()}),this.$router.afterEach(()=>{xs.a.done(),this.isSidebarOpen=!1})}}],Cs={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return fs("layout",t),Wn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},ks=n(14),Os=Object(ks.a)(Cs,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Os,"mixins",ws);const $s=[{name:"v-1151045e",path:"/",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1151045e").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-7687dbe3",path:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7687dbe3").then(n)}},{path:"/advance/5.2.组合注解.html",redirect:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html"},{path:"/advance/5.2.组合注解.html",redirect:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html"},{name:"v-3b4a094a",path:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-3b4a094a").then(n)}},{path:"/advance/5.5.操作注解解析器.html",redirect:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{path:"/advance/5.5.操作注解解析器.html",redirect:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{name:"v-7ade593d",path:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7ade593d").then(n)}},{path:"/advance/5.3.容器的生命周期回调.html",redirect:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html"},{path:"/advance/5.3.容器的生命周期回调.html",redirect:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html"},{name:"v-206a88f7",path:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-206a88f7").then(n)}},{path:"/advance/5.4.反射工厂.html",redirect:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html"},{path:"/advance/5.4.反射工厂.html",redirect:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html"},{name:"v-06e226fd",path:"/advance/5.1.%E7%BC%93%E5%AD%98.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-06e226fd").then(n)}},{path:"/advance/5.1.缓存.html",redirect:"/advance/5.1.%E7%BC%93%E5%AD%98.html"},{path:"/advance/5.1.缓存.html",redirect:"/advance/5.1.%E7%BC%93%E5%AD%98.html"},{name:"v-49ed32b8",path:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-49ed32b8").then(n)}},{path:"/basic/1.4.常见问题.html",redirect:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html"},{path:"/basic/1.4.常见问题.html",redirect:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html"},{name:"v-6c043199",path:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6c043199").then(n)}},{path:"/advance/5.6.类型转换.html",redirect:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html"},{path:"/advance/5.6.类型转换.html",redirect:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html"},{name:"v-a2e60fe0",path:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-a2e60fe0").then(n)}},{path:"/basic/quickstart/1.2.0.快速开始.html",redirect:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html"},{path:"/basic/quickstart/1.2.0.快速开始.html",redirect:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html"},{name:"v-700b7892",path:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-700b7892").then(n)}},{path:"/container/2.0.数据源容器.html",redirect:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.0.数据源容器.html",redirect:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html"},{name:"v-51ee3d19",path:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-51ee3d19").then(n)}},{path:"/basic/quickstart/1.2.2.在spring项目中使用.html",redirect:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.2.在spring项目中使用.html",redirect:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-97ff7a9a",path:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-97ff7a9a").then(n)}},{path:"/container/2.1.本地缓存容器.html",redirect:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.1.本地缓存容器.html",redirect:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html"},{name:"v-b799f18e",path:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b799f18e").then(n)}},{path:"/basic/quickstart/1.2.3.在springboot项目中使用.html",redirect:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.3.在springboot项目中使用.html",redirect:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-7e84bb17",path:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7e84bb17").then(n)}},{path:"/container/2.2.枚举容器.html",redirect:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.2.枚举容器.html",redirect:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html"},{name:"v-b48601fc",path:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b48601fc").then(n)}},{path:"/container/2.3.常量容器.html",redirect:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.3.常量容器.html",redirect:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html"},{name:"v-5d96c30f",path:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-5d96c30f").then(n)}},{path:"/basic/quickstart/1.2.1.在非spring项目中使用.html",redirect:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.1.在非spring项目中使用.html",redirect:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-afd7a946",path:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-afd7a946").then(n)}},{path:"/container/2.6.对象内省.html",redirect:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html"},{path:"/container/2.6.对象内省.html",redirect:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html"},{name:"v-6d10ef40",path:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6d10ef40").then(n)}},{path:"/container/2.4.lambda容器.html",redirect:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.4.lambda容器.html",redirect:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html"},{name:"v-4642376c",path:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4642376c").then(n)}},{path:"/container/2.8.容器提供者.html",redirect:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html"},{path:"/container/2.8.容器提供者.html",redirect:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html"},{name:"v-1d6c8203",path:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1d6c8203").then(n)}},{path:"/container/2.5.方法容器.html",redirect:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.5.方法容器.html",redirect:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html"},{name:"v-6aee24e3",path:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6aee24e3").then(n)}},{path:"/container/2.7.自定义容器.html",redirect:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.7.自定义容器.html",redirect:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html"},{name:"v-a7970784",path:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-a7970784").then(n)}},{path:"/container/2.9.对象容器.html",redirect:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.9.对象容器.html",redirect:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html"},{name:"v-c0e295c2",path:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-c0e295c2").then(n)}},{path:"/basic/1.1.用户指南.html",redirect:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html"},{path:"/basic/1.1.用户指南.html",redirect:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html"},{name:"v-07d72cc6",path:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-07d72cc6").then(n)}},{path:"/basic/1.3.配置文件.html",redirect:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html"},{path:"/basic/1.3.配置文件.html",redirect:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html"},{name:"v-14f016fd",path:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-14f016fd").then(n)}},{path:"/execute/4.1.手动填充.html",redirect:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{path:"/execute/4.1.手动填充.html",redirect:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{name:"v-1fb25314",path:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1fb25314").then(n)}},{path:"/extension/6.1.MybatisPlus扩展.html",redirect:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html"},{path:"/extension/6.1.MybatisPlus扩展.html",redirect:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html"},{name:"v-19857dfe",path:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-19857dfe").then(n)}},{path:"/execute/4.3.操作执行器.html",redirect:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html"},{path:"/execute/4.3.操作执行器.html",redirect:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html"},{name:"v-4c42f052",path:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4c42f052").then(n)}},{path:"/operation/3.0.操作配置.html",redirect:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html"},{path:"/operation/3.0.操作配置.html",redirect:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html"},{name:"v-74c62ac8",path:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-74c62ac8").then(n)}},{path:"/operation/3.1.声明装配操作.html",redirect:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html"},{path:"/operation/3.1.声明装配操作.html",redirect:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html"},{name:"v-54898c6d",path:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-54898c6d").then(n)}},{path:"/operation/3.2.配置属性映射.html",redirect:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html"},{path:"/operation/3.2.配置属性映射.html",redirect:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html"},{name:"v-9c39d86e",path:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-9c39d86e").then(n)}},{path:"/development/配置解析器.html",redirect:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{path:"/development/配置解析器.html",redirect:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{name:"v-4d08fff8",path:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4d08fff8").then(n)}},{path:"/execute/4.2.自动填充.html",redirect:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{path:"/execute/4.2.自动填充.html",redirect:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{name:"v-995c65a0",path:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-995c65a0").then(n)}},{path:"/operation/3.5.操作分组.html",redirect:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html"},{path:"/operation/3.5.操作分组.html",redirect:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html"},{name:"v-031526f1",path:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-031526f1").then(n)}},{path:"/operation/3.4.拆卸嵌套对象.html",redirect:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html"},{path:"/operation/3.4.拆卸嵌套对象.html",redirect:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html"},{name:"v-0b603d28",path:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-0b603d28").then(n)}},{path:"/operation/3.7.操作者接口.html",redirect:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html"},{path:"/operation/3.7.操作者接口.html",redirect:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html"},{name:"v-2c4163e0",path:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-2c4163e0").then(n)}},{path:"/operation/3.3.指定装配处理器.html",redirect:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html"},{path:"/operation/3.3.指定装配处理器.html",redirect:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html"},{name:"v-644d0f52",path:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-644d0f52").then(n)}},{path:"/other/更新日志.html",redirect:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html"},{path:"/other/更新日志.html",redirect:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html"},{name:"v-19618f9e",path:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-19618f9e").then(n)}},{path:"/operation/3.6.操作排序.html",redirect:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html"},{path:"/operation/3.6.操作排序.html",redirect:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html"},{name:"v-915ccd2a",path:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-915ccd2a").then(n)}},{path:"/other/提问的智慧.html",redirect:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html"},{path:"/other/提问的智慧.html",redirect:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html"},{name:"v-3289f112",path:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-3289f112").then(n)}},{path:"/other/源码设计.html",redirect:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html"},{path:"/other/源码设计.html",redirect:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html"},{name:"v-b7c30ce4",path:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b7c30ce4").then(n)}},{path:"/other/联系作者.html",redirect:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"},{path:"/other/联系作者.html",redirect:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"},{path:"*",component:Os}],js={title:"Crane4j",description:"Crane4j, 基于注解的数据关联框架",base:"/crane4j/",headTags:[["link",{rel:"icon",href:"CRANE4J_ICON.png"}]],pages:[{title:"Home",frontmatter:{home:!0,heroImage:"./image-20230220150040070.png",heroText:null,tagline:"强大又好用的数据填充框架~",actionText:"快速上手 →",actionLink:"./basic/1.1.用户指南.md",features:[{title:"开箱即用",details:"结合 springboot 自动装配,一行注解即可启用框架功能,避免繁琐的基本配置"},{title:"上手简单",details:"简单好懂的 API 和全面的注解配置支持,助你轻松上手"},{title:"轻松扩展",details:"结合 spring 依赖注入,轻松替换默认组件,丝滑接入自定义逻辑"},{title:"适用于多种场景",details:"支持分组或嵌套填充,也支持一对多或多对多批量填充,操作粒度最细可到每一个字段"},{title:"丰富的数据源支持",details:"默认即支持字典、枚举、常量类以及可执行方法等类型数据源,简单操作即可扩展更多数据源"},{title:"强大的扩展功能",details:"提供自动填充,多线程填充,缓存、动态表达式等扩展功能,还支持 mybatis-plus 等扩展插件"}]},regularPath:"/",relativePath:"README.md",key:"v-1151045e",path:"/"},{title:"组合注解",frontmatter:{},regularPath:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",relativePath:"advance/5.2.组合注解.md",key:"v-7687dbe3",path:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",headers:[{level:2,title:"组合注解",slug:"组合注解"}]},{title:"操作注解解析器",frontmatter:{},regularPath:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",relativePath:"advance/5.5.操作注解解析器.md",key:"v-3b4a094a",path:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",headers:[{level:2,title:"操作注解解析器",slug:"操作注解解析器"}]},{title:"5.3.1.容器生命周期处理器",frontmatter:{},regularPath:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",relativePath:"advance/5.3.容器的生命周期回调.md",key:"v-7ade593d",path:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",headers:[{level:2,title:"5.3.1.容器生命周期处理器",slug:"_5-3-1-容器生命周期处理器"},{level:2,title:"5.3.2.容器的生命周期回调",slug:"_5-3-2-容器的生命周期回调"}]},{title:"反射工厂",frontmatter:{},regularPath:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",relativePath:"advance/5.4.反射工厂.md",key:"v-206a88f7",path:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",headers:[{level:2,title:"反射工厂",slug:"反射工厂"}]},{title:"概述",frontmatter:{},regularPath:"/advance/5.1.%E7%BC%93%E5%AD%98.html",relativePath:"advance/5.1.缓存.md",key:"v-06e226fd",path:"/advance/5.1.%E7%BC%93%E5%AD%98.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"5.1.1.缓存管理器",slug:"_5-1-1-缓存管理器"},{level:2,title:"5.1.2.结合数据源容器使用",slug:"_5-1-2-结合数据源容器使用"},{level:2,title:"5.1.3.配置缓存容器",slug:"_5-1-3-配置缓存容器"},{level:3,title:"5.1.3.1. 手动替换",slug:"_5-1-3-1-手动替换"},{level:3,title:"5.1.3.2. 添加注解",slug:"_5-1-3-2-添加注解"},{level:3,title:"5.1.3.3. 配置文件",slug:"_5-1-3-3-配置文件"}]},{title:"1、填充不生效?",frontmatter:{},regularPath:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",relativePath:"basic/1.4.常见问题.md",key:"v-49ed32b8",path:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",headers:[{level:2,title:"1、填充不生效?",slug:"_1、填充不生效"},{level:2,title:"2、如何实现嵌套填充?",slug:"_2、如何实现嵌套填充"},{level:2,title:"3、如何实现级联填充?",slug:"_3、如何实现级联填充"},{level:2,title:"4、如何处理一对多的情况?",slug:"_4、如何处理一对多的情况"},{level:2,title:"5、键字段可以是按分隔符拼接的字符串吗?",slug:"_5、键字段可以是按分隔符拼接的字符串吗"},{level:2,title:"6、键字段可以是集合或者数组吗?",slug:"_6、键字段可以是集合或者数组吗"},{level:2,title:"7、为什么使用异步执行器的时候报错?",slug:"_7、为什么使用异步执行器的时候报错"},{level:2,title:"8、怎么刷新容器的数据 ?",slug:"_8、怎么刷新容器的数据"},{level:2,title:"9、怎么忽略掉某些字段不进行填充?",slug:"_9、怎么忽略掉某些字段不进行填充"},{level:2,title:"10、为什么 @ContainerMethod 注解不生效?",slug:"_10、为什么-containermethod-注解不生效"},{level:2,title:"11、为什么 @AutoOperate 注解不生效?",slug:"_11、为什么-autooperate-注解不生效"},{level:2,title:"12、为什么引了 guava 和 hutool ?",slug:"_12、为什么引了-guava-和-hutool"},{level:2,title:"13、支持 jdk9+ / springboot3 吗?",slug:"_13、支持-jdk9-springboot3-吗"},{level:2,title:"14、容器可以做一些自定义的初始化/销毁操作吗?",slug:"_14、容器可以做一些自定义的初始化-销毁操作吗"},{level:2,title:"15、可以支持同时根据多个 key 字段填充数据吗?",slug:"_15、可以支持同时根据多个-key-字段填充数据吗"}]},{title:"类型转换",frontmatter:{},regularPath:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",relativePath:"advance/5.6.类型转换.md",key:"v-6c043199",path:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",headers:[{level:2,title:"类型转换",slug:"类型转换"}]},{title:"快速开始",frontmatter:{},regularPath:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",relativePath:"basic/quickstart/1.2.0.快速开始.md",key:"v-a2e60fe0",path:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",headers:[{level:2,title:"快速开始",slug:"快速开始"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.0.数据源容器.md",key:"v-700b7892",path:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.0.1.默认实现",slug:"_2-0-1-默认实现"},{level:2,title:"2.0.2.注册容器",slug:"_2-0-2-注册容器"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.2.在spring项目中使用.md",key:"v-51ee3d19",path:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:3,title:"引入依赖",slug:"引入依赖"},{level:3,title:"启用配置",slug:"启用配置"},{level:2,title:"配置数据源",slug:"配置数据源"},{level:2,title:"配置装配操作",slug:"配置装配操作"},{level:2,title:"执行装配操作",slug:"执行装配操作"},{level:2,title:"执行嵌套填充",slug:"执行嵌套填充"}]},{title:"本地缓存容器",frontmatter:{},regularPath:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.1.本地缓存容器.md",key:"v-97ff7a9a",path:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"本地缓存容器",slug:"本地缓存容器"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.3.在springboot项目中使用.md",key:"v-b799f18e",path:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:2,title:"使用",slug:"使用"}]},{title:"2.2.1. 基本使用",frontmatter:{},regularPath:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.2.枚举容器.md",key:"v-7e84bb17",path:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"2.2.1. 基本使用",slug:"_2-2-1-基本使用"},{level:2,title:"2.2.2. 可选注解",slug:"_2-2-2-可选注解"},{level:2,title:"2.2.3.枚举装配",slug:"_2-2-3-枚举装配"}]},{title:"2.3.1. 基本使用",frontmatter:{},regularPath:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.3.常量容器.md",key:"v-b48601fc",path:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"2.3.1. 基本使用",slug:"_2-3-1-基本使用"},{level:2,title:"2.3.2. 可选注解",slug:"_2-3-2-可选注解"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.1.在非spring项目中使用.md",key:"v-5d96c30f",path:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:3,title:"引入依赖",slug:"引入依赖"},{level:3,title:"全局配置",slug:"全局配置"},{level:3,title:"启用填充工具",slug:"启用填充工具"},{level:3,title:"启用扩展功能",slug:"启用扩展功能"},{level:2,title:"配置数据源",slug:"配置数据源"},{level:2,title:"配置装配操作",slug:"配置装配操作"},{level:2,title:"执行装配操作",slug:"执行装配操作"},{level:2,title:"执行嵌套填充",slug:"执行嵌套填充"}]},{title:"对象内省",frontmatter:{},regularPath:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",relativePath:"container/2.6.对象内省.md",key:"v-afd7a946",path:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",headers:[{level:2,title:"对象内省",slug:"对象内省"}]},{title:"Lambda容器",frontmatter:{},regularPath:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.4.lambda容器.md",key:"v-6d10ef40",path:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"Lambda容器",slug:"lambda容器"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",relativePath:"container/2.8.容器提供者.md",key:"v-4642376c",path:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.8.1.注册",slug:"_2-8-1-注册"},{level:2,title:"2.8.2.使用",slug:"_2-8-2-使用"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.5.方法容器.md",key:"v-1d6c8203",path:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.5.1.声明方法数据源",slug:"_2-5-1-声明方法数据源"},{level:2,title:"2.5.2.对结果分组",slug:"_2-5-2-对结果分组"},{level:3,title:"2.5.2.1.一对一",slug:"_2-5-2-1-一对一"},{level:3,title:"2.5.2.2.一对多",slug:"_2-5-2-2-一对多"},{level:3,title:"2.5.2.3.不分组",slug:"_2-5-2-3-不分组"},{level:2,title:"2.5.4.数据源容器工厂",slug:"_2-5-4-数据源容器工厂"},{level:2,title:"2.5.5.注册方法数据源容器",slug:"_2-5-5-注册方法数据源容器"}]},{title:"自定义容器",frontmatter:{},regularPath:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.7.自定义容器.md",key:"v-6aee24e3",path:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"自定义容器",slug:"自定义容器"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.9.对象容器.md",key:"v-a7970784",path:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"使用",slug:"使用"}]},{frontmatter:{},regularPath:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",relativePath:"basic/1.1.用户指南.md",key:"v-c0e295c2",path:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",headers:[{level:2,title:"1.1.1.为什么写?",slug:"_1-1-1-为什么写"},{level:2,title:"1.1.2.它解决了什么问题?",slug:"_1-1-2-它解决了什么问题"},{level:2,title:"1.1.3.它有什么特性?",slug:"_1-1-3-它有什么特性"},{level:2,title:"1.1.4.如何使用?",slug:"_1-1-4-如何使用"}]},{frontmatter:{},regularPath:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",relativePath:"basic/1.3.配置文件.md",key:"v-07d72cc6",path:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",headers:[{level:2,title:"1.3.1.反射",slug:"_1-3-1-反射"},{level:3,title:"1.3.1.1.是否启用字节码反射",slug:"_1-3-1-1-是否启用字节码反射"},{level:3,title:"1.3.1.2.是否支持处理Map对象",slug:"_1-3-1-2-是否支持处理map对象"},{level:3,title:"1.3.1.3.是否支持链式操作符",slug:"_1-3-1-3-是否支持链式操作符"},{level:2,title:"1.3.2.容器",slug:"_1-3-2-容器"},{level:3,title:"1.3.2.1.扫描常量容器",slug:"_1-3-2-1-扫描常量容器"},{level:3,title:"1.3.2.2.扫描枚举容器",slug:"_1-3-2-2-扫描枚举容器"},{level:3,title:"1.3.2.3.扫描方法容器",slug:"_1-3-2-3-扫描方法容器"},{level:3,title:"1.3.2.4.容器缓存配置",slug:"_1-3-2-4-容器缓存配置"},{level:2,title:"1.3.3.自动填充",slug:"_1-3-3-自动填充"},{level:2,title:"1.3.4.操作配置预解析",slug:"_1-3-4-操作配置预解析"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",relativePath:"execute/4.1.手动填充.md",key:"v-14f016fd",path:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.1.1.使用执行器手动填充",slug:"_4-1-1-使用执行器手动填充"},{level:2,title:"4.1.2.使用 OperateTemplate",slug:"_4-1-2-使用-operatetemplate"}]},{title:"概述",frontmatter:{},regularPath:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",relativePath:"extension/6.1.MybatisPlus扩展.md",key:"v-1fb25314",path:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"6.1.1.安装",slug:"_6-1-1-安装"},{level:2,title:"6.1.2.注册Mapper",slug:"_6-1-2-注册mapper"},{level:2,title:"6.1.3.基本使用",slug:"_6-1-3-基本使用"},{level:3,title:"6.1.3.1.根据主键查询全部字段",slug:"_6-1-3-1-根据主键查询全部字段"},{level:3,title:"6.1.3.2.根据主键查询指定字段",slug:"_6-1-3-2-根据主键查询指定字段"},{level:3,title:"6.1.3.3.根据指定外键查询全部字段",slug:"_6-1-3-3-根据指定外键查询全部字段"},{level:3,title:"6.1.3.4.根据指定外键查询指定字段",slug:"_6-1-3-4-根据指定外键查询指定字段"},{level:2,title:"6.1.4.指定查询字段 SQL",slug:"_6-1-4-指定查询字段-sql"},{level:2,title:"6.1.5.指定映射类型",slug:"_6-1-5-指定映射类型"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",relativePath:"execute/4.3.操作执行器.md",key:"v-19857dfe",path:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.3.1.可选实现",slug:"_4-3-1-可选实现"},{level:2,title:"4.3.2.使用",slug:"_4-3-2-使用"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",relativePath:"operation/3.0.操作配置.md",key:"v-4c42f052",path:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",headers:[{level:2,title:"概述",slug:"概述"}]},{title:"3.1.1.在属性上声明",frontmatter:{},regularPath:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",relativePath:"operation/3.1.声明装配操作.md",key:"v-74c62ac8",path:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",headers:[{level:2,title:"3.1.1.在属性上声明",slug:"_3-1-1-在属性上声明"},{level:2,title:"3.1.2.在类上声明",slug:"_3-1-2-在类上声明"},{level:2,title:"3.1.3.声明多个操作",slug:"_3-1-3-声明多个操作"},{level:2,title:"3.1.4.动态的表达式",slug:"_3-1-4-动态的表达式"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",relativePath:"operation/3.2.配置属性映射.md",key:"v-54898c6d",path:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.2.1.将属性映射到属性",slug:"_3-2-1-将属性映射到属性"},{level:2,title:"3.2.2.将对象映射到属性",slug:"_3-2-2-将对象映射到属性"},{level:2,title:"3.2.3.将值映射到键属性",slug:"_3-2-3-将值映射到键属性"},{level:2,title:"3.2.4.批量映射",slug:"_3-2-4-批量映射"},{level:2,title:"3.2.5.映射模板",slug:"_3-2-5-映射模板"},{level:2,title:"3.2.6.链式操作符",slug:"_3-2-6-链式操作符"}]},{title:"一、什么是配置解析器",frontmatter:{},regularPath:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",relativePath:"development/配置解析器.md",key:"v-9c39d86e",path:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",headers:[{level:2,title:"一、什么是配置解析器",slug:"一、什么是配置解析器"},{level:2,title:"二、运行流程",slug:"二、运行流程"},{level:2,title:"三、不同版本的实现",slug:"三、不同版本的实现"},{level:3,title:"1、crane 时期",slug:"_1、crane-时期"},{level:3,title:"2、v1.0 - 1.2",slug:"_2、v1-0-1-2"},{level:3,title:"3、v1.3",slug:"_3、v1-3"},{level:3,title:"4、v2.0",slug:"_4、v2-0"},{level:2,title:"四、优化和调试",slug:"四、优化和调试"},{level:3,title:"1、可以打断点的关键方法",slug:"_1、可以打断点的关键方法"},{level:3,title:"2、可以优化的地方",slug:"_2、可以优化的地方"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",relativePath:"execute/4.2.自动填充.md",key:"v-4d08fff8",path:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.2.1.填充方法返回值",slug:"_4-2-1-填充方法返回值"},{level:2,title:"4.2.2.自动填充方法参数",slug:"_4-2-2-自动填充方法参数"},{level:2,title:"4.2.3.自动类型推断",slug:"_4-2-3-自动类型推断"},{level:2,title:"4.2.4.包装类提取",slug:"_4-2-4-包装类提取"},{level:2,title:"4.2.5.应用条件表达式",slug:"_4-2-5-应用条件表达式"},{level:2,title:"4.2.6.分组填充",slug:"_4-2-6-分组填充"},{level:2,title:"4.2.7.指定执行器",slug:"_4-2-7-指定执行器"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",relativePath:"operation/3.5.操作分组.md",key:"v-995c65a0",path:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.5.1.为操作分组",slug:"_3-5-1-为操作分组"},{level:2,title:"3.5.2.按分组规则执行操作",slug:"_3-5-2-按分组规则执行操作"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",relativePath:"operation/3.4.拆卸嵌套对象.md",key:"v-031526f1",path:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.4.1.在属性上声明",slug:"_3-4-1-在属性上声明"},{level:2,title:"3.4.2.在类上声明",slug:"_3-4-2-在类上声明"},{level:2,title:"3.4.3.自动类型推断",slug:"_3-4-3-自动类型推断"},{level:2,title:"3.4.4.拆卸操作处理器",slug:"_3-4-4-拆卸操作处理器"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",relativePath:"operation/3.7.操作者接口.md",key:"v-0b603d28",path:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.7.1.基本使用",slug:"_3-7-1-基本使用"},{level:2,title:"3.7.2.在 Spring 中使用",slug:"_3-7-2-在-spring-中使用"},{level:2,title:"3.7.3.动态数据源容器",slug:"_3-7-3-动态数据源容器"},{level:3,title:"3.7.3.1.声明参数为容器",slug:"_3-7-3-1-声明参数为容器"},{level:3,title:"3.7.3.2.使用参数容器",slug:"_3-7-3-2-使用参数容器"},{level:3,title:"3.7.3.3.参数适配器",slug:"_3-7-3-3-参数适配器"},{level:2,title:"3.7.4.指定执行器和解析器",slug:"_3-7-4-指定执行器和解析器"},{level:2,title:"3.7.5.代理方法工厂",slug:"_3-7-5-代理方法工厂"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",relativePath:"operation/3.3.指定装配处理器.md",key:"v-2c4163e0",path:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.2.1.使用",slug:"_3-2-1-使用"},{level:2,title:"3.2.2.一对多装配",slug:"_3-2-2-一对多装配"},{level:2,title:"3.2.3.多对多装配",slug:"_3-2-3-多对多装配"}]},{title:"1.0.0 (2023-03-23)",frontmatter:{},regularPath:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",relativePath:"other/更新日志.md",key:"v-644d0f52",path:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",headers:[{level:2,title:"1.0.0 (2023-03-23)",slug:"_1-0-0-2023-03-23"},{level:2,title:"1.1.0 (2023-03-30)",slug:"_1-1-0-2023-03-30"},{level:2,title:"1.2.0 (2023-04-09)",slug:"_1-2-0-2023-04-09"},{level:2,title:"1.3.0-ALPHA (2023-05-10)",slug:"_1-3-0-alpha-2023-05-10"},{level:2,title:"2.0.0-ALPHA (2023-07-08)",slug:"_2-0-0-alpha-2023-07-08"},{level:2,title:"2.0.0-BATE (2023-07-30)",slug:"_2-0-0-bate-2023-07-30"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",relativePath:"operation/3.6.操作排序.md",key:"v-19618f9e",path:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.6.1.指定排序值",slug:"_3-6-1-指定排序值"},{level:2,title:"3.6.2.按顺序执行",slug:"_3-6-2-按顺序执行"}]},{frontmatter:{},regularPath:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",relativePath:"other/提问的智慧.md",key:"v-915ccd2a",path:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",headers:[{level:2,title:"在提问之前",slug:"在提问之前"},{level:2,title:"当你提问时",slug:"当你提问时"},{level:3,title:"慎选提问的论坛",slug:"慎选提问的论坛"},{level:3,title:"Stack Overflow",slug:"stack-overflow"},{level:3,title:"网站和 IRC 论坛",slug:"网站和-irc-论坛"},{level:3,title:"第二步,使用项目邮件列表",slug:"第二步-使用项目邮件列表"},{level:3,title:"使用有意义且描述明确的标题",slug:"使用有意义且描述明确的标题"},{level:3,title:"使问题容易回复",slug:"使问题容易回复"},{level:3,title:"",slug:"使用清晰、正确、精准且合乎语法的语句"},{level:3,title:"使用易于读取且标准的文件格式发送问题",slug:"使用易于读取且标准的文件格式发送问题"},{level:3,title:"精确地描述问题并言之有物",slug:"精确地描述问题并言之有物"},{level:3,title:"话不在多而在精",slug:"话不在多而在精"},{level:3,title:"别动辄声称找到 Bug",slug:"别动辄声称找到-bug"},{level:3,title:"低声下气不能代替你的功课",slug:"低声下气不能代替你的功课"},{level:3,title:"描述问题症状而非你的猜测",slug:"描述问题症状而非你的猜测"},{level:3,title:"按发生时间先后列出问题症状",slug:"按发生时间先后列出问题症状"},{level:3,title:"描述目标而不是过程",slug:"描述目标而不是过程"},{level:3,title:"别要求使用私人电邮回复",slug:"别要求使用私人电邮回复"},{level:3,title:"清楚明确地表达你的问题以及需求",slug:"清楚明确地表达你的问题以及需求"},{level:3,title:"询问有关代码的问题时",slug:"询问有关代码的问题时"},{level:3,title:"别把自己家庭作业的问题贴上来",slug:"别把自己家庭作业的问题贴上来"},{level:3,title:"去掉无意义的提问句",slug:"去掉无意义的提问句"},{level:3,title:"即使你很急也不要在标题写紧急",slug:"即使你很急也不要在标题写紧急"},{level:3,title:"礼多人不怪,而且有时还很有帮助",slug:"礼多人不怪-而且有时还很有帮助"},{level:3,title:"问题解决后,加个简短的补充说明",slug:"问题解决后-加个简短的补充说明"},{level:2,title:"如何解读答案",slug:"如何解读答案"},{level:3,title:"RTFM 和 STFW:如何知道你已完全搞砸了",slug:"rtfm-和-stfw-如何知道你已完全搞砸了"},{level:3,title:"如果还是搞不懂",slug:"如果还是搞不懂"},{level:3,title:"处理无礼的回应",slug:"处理无礼的回应"},{level:2,title:"如何避免扮演失败者",slug:"如何避免扮演失败者"},{level:2,title:"不该问的问题",slug:"不该问的问题"},{level:2,title:"好问题与蠢问题",slug:"好问题与蠢问题"},{level:2,title:"如果得不到回答",slug:"如果得不到回答"},{level:2,title:"如何更好地回答问题",slug:"如何更好地回答问题"},{level:2,title:"相关资源",slug:"相关资源"},{level:2,title:"鸣谢",slug:"鸣谢"}]},{title:"执行流程",frontmatter:{},regularPath:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",relativePath:"other/源码设计.md",key:"v-3289f112",path:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",headers:[{level:2,title:"执行流程",slug:"执行流程"},{level:2,title:"操作配置 & 配置解析器",slug:"操作配置-配置解析器"},{level:2,title:"操作处理器 & 操作执行器",slug:"操作处理器-操作执行器"},{level:2,title:"数据源容器 & 属性映射",slug:"数据源容器-属性映射"},{level:2,title:"设计原则",slug:"设计原则"}]},{frontmatter:{},regularPath:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html",relativePath:"other/联系作者.md",key:"v-b7c30ce4",path:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"}],themeConfig:{sidebarDepth:3,nav:[{text:"首页",link:"/"},{text:"源码",items:[{text:"GitHub",link:"https://github.com/opengoofy/crane4j"},{text:"Gitee",link:"https://gitee.com/CreateSequence/crane4j"}]},{text:"关于作者",items:[{text:"Github",link:"https://github.com/Createsequence/"},{text:"Gitee",link:"https://gitee.com/CreateSequence"},{text:"Blog",link:"https://blog.xiajibagao.top"}]},{text:"关于我们",link:"https://github.com/opengoofy"}],sidebar:[{title:"1.基础",collapsable:!1,children:[{title:"1.1.用户指南",path:"/basic/1.1.用户指南.md"},{title:"1.2.快速开始",path:"/basic/quickstart/1.2.0.快速开始.html",children:[{title:"1.2.1.在非spring项目中使用",path:"/basic/quickstart/1.2.1.在非spring项目中使用.md"},{title:"1.2.2.在spring项目中使用",path:"/basic/quickstart/1.2.2.在spring项目中使用.md"},{title:"1.2.3.在springboot项目中使用",path:"/basic/quickstart/1.2.3.在springboot项目中使用.md"}]},{title:"1.3.配置文件",path:"/basic/1.3.配置文件.md"},{title:"1.4.常见问题",path:"/basic/1.4.常见问题.md"}]},{title:"2.数据源容器",path:"/container/2.0.数据源容器.html",collapsable:!1,children:[{title:"2.1.本地缓存",path:"/container/2.1.本地缓存容器.md"},{title:"2.2.枚举",path:"/container/2.2.枚举容器.md"},{title:"2.3.常量",path:"/container/2.3.常量容器.md"},{title:"2.4.lambda表达式",path:"/container/2.4.lambda容器.md"},{title:"2.5.可调用方法",path:"/container/2.5.方法容器.md"},{title:"2.6.对象内省",path:"/container/2.6.对象内省.md"},{title:"2.7.接口/自定义",path:"/container/2.7.自定义容器.md"},{title:"2.8.容器提供者",path:"/container/2.8.容器提供者.md"},{title:"2.9.对象容器",path:"/container/2.9.对象容器.md"}]},{title:"3.操作配置",collapsable:!1,path:"/operation/3.0.操作配置.html",children:[{title:"3.1.声明装配操作",path:"/operation/3.1.声明装配操作.md"},{title:"3.2.配置属性映射",path:"/operation/3.2.配置属性映射.md"},{title:"3.3.指定装配处理器",path:"/operation/3.3.指定装配处理器.md"},{title:"3.4.拆卸嵌套对象",path:"/operation/3.4.拆卸嵌套对象.md"},{title:"3.5.操作分组",path:"/operation/3.5.操作分组.md"},{title:"3.6.操作排序",path:"/operation/3.6.操作排序.md"},{title:"3.7.操作者接口",path:"/operation/3.7.操作者接口.md"}]},{title:"4.执行操作",collapsable:!1,children:[{title:"4.1.手动填充",path:"/execute/4.1.手动填充.md"},{title:"4.2.自动填充",path:"/execute/4.2.自动填充.md"},{title:"4.3.操作执行器",path:"/execute/4.3.操作执行器.md"}]},{title:"5.高级特性",collapsable:!1,children:[{title:"5.1.缓存",path:"/advance/5.1.缓存.md"},{title:"5.2.组合注解",path:"/advance/5.2.组合注解.md"},{title:"5.3.容器的生命周期回调",path:"/advance/5.3.容器的生命周期回调.md"},{title:"5.4.反射工厂",path:"/advance/5.4.反射工厂.md"},{title:"5.5.操作注解解析器",path:"/advance/5.5.操作注解解析器.md"},{title:"5.5.类型转换",path:"/advance/5.6.类型转换.md"}]},{title:"6.扩展组件",collapsable:!1,children:[{title:"6.1.MybatisPlus扩展.md",path:"/extension/6.1.MybatisPlus扩展.md"}]},{title:"其他",collapsable:!1,children:[{title:"联系作者",path:"/other/联系作者.md"},{title:"提问的智慧",path:"/other/提问的智慧.md"},{title:"源码设计",path:"/other/源码设计.md"},{title:"更新日志",path:"/other/更新日志.md"}]}]}};n(234);Wn.component("Badge",()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,325))),Wn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,282))),Wn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,283)));n(235);var Ss=[{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{}],Ds=[];class Ps extends class{constructor(){this.store=new Wn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Wn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(Ps.prototype,{getPageAsyncComponent:as,getLayoutAsyncComponent:ss,getAsyncComponent:cs,getVueComponent:ls});var Ts={install(t){const e=new Ps;t.$vuepress=e,t.prototype.$vuepress=e}};function Ls(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var Fs={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return fs("pageKey",e),Wn.component(e)||Wn.component(e,as(e)),Wn.component(e)?t(e):t("")}},Rs={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},Ms={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Is=(n(236),n(237),Object(ks.a)(Ms,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Ns={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Wn.config.productionTip=!1,Wn.use(Va),Wn.use(Ts),Wn.mixin(function(t,e,n=Wn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Wn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Ls(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Ls(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Ls(t,o)?r(o):Ls(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(Ss.filter(t=>"function"==typeof t).map(e=>e({Vue:Wn,options:r,router:n,siteData:js,isServer:t})))}catch(t){console.error(t)}return{app:new Wn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},Ds.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file +var r=Object.freeze({}),o=Array.isArray;function i(t){return null==t}function a(t){return null!=t}function s(t){return!0===t}function c(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function l(t){return"function"==typeof t}function u(t){return null!==t&&"object"==typeof t}var f=Object.prototype.toString;function p(t){return"[object Object]"===f.call(t)}function h(t){return"[object RegExp]"===f.call(t)}function d(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||p(t)&&t.toString===f?JSON.stringify(t,null,2):String(t)}function E(t){var e=parseFloat(t);return isNaN(e)?t:e}function g(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var _=Object.prototype.hasOwnProperty;function A(t,e){return _.call(t,e)}function B(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,w=B((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),C=B((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),k=/\B([A-Z])/g,O=B((function(t){return t.replace(k,"-$1").toLowerCase()}));var $=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function j(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function S(t,e){for(var n in e)t[n]=e[n];return t}function D(t){for(var e={},n=0;n0,Q=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var Z=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var tt,et=J&&J.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(G)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function st(t){return"function"==typeof t&&/native code/.test(t.toString())}var ct,lt="undefined"!=typeof Symbol&&st(Symbol)&&"undefined"!=typeof Reflect&&st(Reflect.ownKeys);ct="undefined"!=typeof Set&&st(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var ut=null;function ft(t){void 0===t&&(t=null),t||ut&&ut._scope.off(),ut=t,t&&t._scope.on()}var pt=function(){function t(t,e,n,r,o,i,a,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ht=function(t){void 0===t&&(t="");var e=new pt;return e.text=t,e.isComment=!0,e};function dt(t){return new pt(void 0,void 0,void 0,String(t))}function vt(t){var e=new pt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,Et=[],gt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,Et.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,r=e.length;n0&&(Jt((l=t(l,"".concat(n||"","_").concat(r)))[0])&&Jt(f)&&(p[u]=dt(f.text+l[0].text),l.shift()),p.push.apply(p,l)):c(l)?Jt(f)?p[u]=dt(f.text+l):""!==l&&p.push(dt(l)):Jt(l)&&Jt(f)?p[u]=dt(f.text+l.text):(s(e._isVList)&&a(l.tag)&&i(l.key)&&a(n)&&(l.key="__vlist".concat(n,"_").concat(r,"__")),p.push(l)));return p}(t):void 0}function Jt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,r,i,s,c=null;if(o(t)||"string"==typeof t)for(c=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!a,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&o&&o!==r&&c===o.$key&&!a&&!o.$hasNormal)return o;for(var l in i={},e)e[l]&&"$"!==l[0]&&(i[l]=ve(t,n,l,e[l]))}else i={};for(var u in n)u in i||(i[u]=me(n,u));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",s),H(i,"$key",c),H(i,"$hasNormal",a),i}function ve(t,e,n,r){var i=function(){var e=ut;ft(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Gt(n))&&n[0];return ft(e),n&&(!i||1===n.length&&i.isComment&&!he(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function me(t,e){return function(){return t[e]}}function Ee(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ge(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ge(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||be(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:$(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return It(t,e,n)}))}}}function ge(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,ye(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function ye(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function be(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var _e=null;function Ae(t,e){return(t.__esModule||lt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),u(t)?e.extend(t):t}function Be(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(cn=function(){return ln.now()})}var un=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function fn(){var t,e;for(sn=cn(),on=!0,tn.sort(un),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Me(fn))}}function hn(t,e){if(t){for(var n=Object.create(null),r=lt?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!A(o,"default"))a=!1;else if(""===a||a===O(t)){var c=Ln(String,o.type);(c<0||s-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!h(t)&&t.test(e)}function Xn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Yn(n,i,r,o)}}}function Yn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,b(n,e)}Wn.prototype._init=function(t){var e=this;e._uid=Vn++,e._isVue=!0,e.__v_skip=!0,e._scope=new qt(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=$n(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ge(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=fe(e._renderChildren,o),t.$scopedSlots=n?de(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return xe(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return xe(t,e,n,r,o,!0)};var i=n&&n.data;St(t,"$attrs",i&&i.attrs||r,null,!0),St(t,"$listeners",e._parentListeners||r,null,!0)}(e),Ze(e,"beforeCreate",void 0,!1),function(t){var e=hn(t.$options.inject,t);e&&(kt(!1),Object.keys(e).forEach((function(n){St(t,n,e[n])})),kt(!0))}(e),Mn(e),function(t){var e=t.$options.provide;if(e){var n=l(e)?e.call(t):e;if(!u(n))return;for(var r=Ut(t),o=lt?Reflect.ownKeys(n):Object.keys(n),i=0;i1?j(n):n;for(var r=j(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Yn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Jn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Jn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Be(t),n=e&&e.componentOptions;if(n){var r=Gn(n),o=this.include,i=this.exclude;if(o&&(!r||!Jn(o,r))||i&&r&&Jn(i,r))return e;var a=this.cache,s=this.keys,c=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[c]?(e.componentInstance=a[c].componentInstance,b(s,c),s.push(c)):(this.vnodeToCache=e,this.keyToCache=c),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return U}};Object.defineProperty(t,"config",e),t.util={warn:An,extend:S,mergeOptions:$n,defineReactive:St},t.set=Dt,t.delete=Pt,t.nextTick=Me,t.observable=function(t){return jt(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,S(t.options.components,Zn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=j(arguments,1);return n.unshift(this),l(t.install)?t.install.apply(t,n):l(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=$n(this.options,t),this}}(t),Kn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&p(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&l(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:it}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:dn}),Wn.version="2.7.14";var tr=g("style,class"),er=g("input,textarea,option,select,progress"),nr=g("contenteditable,draggable,spellcheck"),rr=g("events,caret,typing,plaintext-only"),or=g("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},sr=function(t){return ar(t)?t.slice(6,t.length):""},cr=function(t){return null==t||!1===t};function lr(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=ur(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=ur(e,n.data));return function(t,e){if(a(t)||a(e))return fr(t,pr(e));return""}(e.staticClass,e.class)}function ur(t,e){return{staticClass:fr(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function fr(t,e){return t?e?t+" "+e:t:e||""}function pr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?Fr(t,e,n):or(e)?cr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return cr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?cr(n)?t.removeAttributeNS(ir,sr(e)):t.setAttributeNS(ir,e,n):Fr(t,e,n)}function Fr(t,e,n){if(cr(n))t.removeAttribute(e);else{if(X&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Rr={create:Tr,update:Tr};function Mr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var s=lr(e),c=n._transitionClasses;a(c)&&(s=fr(s,pr(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var Ir,Nr={create:Mr,update:Mr};function qr(t,e,n){var r=Ir;return function o(){var i=e.apply(null,arguments);null!==i&&Vr(t,o,n,r)}}var Ur=je&&!(et&&Number(et[1])<=53);function zr(t,e,n,r){if(Ur){var o=sn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ir.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Vr(t,e,n,r){(r||Ir).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Ir=e.elm||t.elm,function(t){if(a(t.__r)){var e=X?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,r,zr,Vr,qr,e.context),Ir=void 0}}var Wr,Kr={create:Hr,update:Hr,destroy:function(t){return Hr(t,Br)}};function Gr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,o=e.elm,c=t.data.domProps||{},l=e.data.domProps||{};for(n in(a(l.__ob__)||s(l._v_attr_proxy))&&(l=e.data.domProps=S({},l)),c)n in l||(o[n]="");for(n in l){if(r=l[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===c[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var u=i(r)?"":String(r);Jr(o,u)&&(o.value=u)}else if("innerHTML"===n&&vr(o.tagName)&&i(o.innerHTML)){(Wr=Wr||document.createElement("div")).innerHTML="".concat(r,"");for(var f=Wr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;f.firstChild;)o.appendChild(f.firstChild)}else if(r!==c[n])try{o[n]=r}catch(t){}}}}function Jr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(a(r)){if(r.number)return E(n)!==E(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xr={create:Gr,update:Gr},Yr=B((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Qr(t){var e=Zr(t.style);return t.staticStyle?S(t.staticStyle,e):e}function Zr(t){return Array.isArray(t)?D(t):"string"==typeof t?Yr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(O(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(co).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function uo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(co).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function fo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&S(e,po(t.name||"v")),S(e,t),e}return"string"==typeof t?po(t):void 0}}var po=B((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ho=G&&!Y,vo="transition",mo="transitionend",Eo="animation",go="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(vo="WebkitTransition",mo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Eo="WebkitAnimation",go="webkitAnimationEnd"));var yo=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function bo(t){yo((function(){yo(t)}))}function _o(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),lo(t,e))}function Ao(t,e){t._transitionClasses&&b(t._transitionClasses,e),uo(t,e)}function Bo(t,e,n){var r=wo(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s="transition"===o?mo:go,c=0,l=function(){t.removeEventListener(s,u),n()},u=function(e){e.target===t&&++c>=a&&l()};setTimeout((function(){c0&&(n="transition",u=a,f=i.length):"animation"===e?l>0&&(n="animation",u=l,f=c.length):f=(n=(u=Math.max(a,l))>0?a>l?"transition":"animation":null)?"transition"===n?i.length:c.length:0,{type:n,timeout:u,propCount:f,hasTransform:"transition"===n&&xo.test(r[vo+"Property"])}}function Co(t,e){for(;t.length1}function Do(t,e){!0!==e.data.show&&Oo(e)}var Po=function(t){var e,n,r={},l=t.modules,u=t.nodeOps;for(e=0;ed?b(t,i(n[E+1])?null:n[E+1].elm,n,h,E,r):h>E&&A(e,f,d)}(f,v,E,n,l):a(E)?(a(t.text)&&u.setTextContent(f,""),b(f,null,E,0,E.length-1,n)):a(v)?A(v,0,v.length-1):a(t.text)&&u.setTextContent(f,""):t.text!==e.text&&u.setTextContent(f,e.text),a(d)&&a(h=d.hook)&&a(h=h.postpatch)&&h(t,e)}}}function C(t,e,n){if(s(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(F(Mo(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Ro(t,e){return e.every((function(e){return!F(e,t)}))}function Mo(t){return"_value"in t?t._value:t.value}function Io(t){t.target.composing=!0}function No(t){t.target.composing&&(t.target.composing=!1,qo(t.target,"input"))}function qo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Uo(t){return!t.componentInstance||t.data&&t.data.transition?t:Uo(t.componentInstance._vnode)}var zo={model:To,show:{bind:function(t,e,n){var r=e.value,o=(n=Uo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,Oo(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=Uo(n)).data&&n.data.transition?(n.data.show=!0,r?Oo(n,(function(){t.style.display=t.__vOriginalDisplay})):$o(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Vo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(Be(e.children)):t}function Wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[w(r)]=o[r];return e}function Ko(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Go=function(t){return t.tag||he(t)},Jo=function(t){return"show"===t.name},Xo={name:"transition",props:Vo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Go)).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=Ho(o);if(!i)return o;if(this._leaving)return Ko(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=Wo(this),l=this._vnode,u=Ho(l);if(i.data.directives&&i.data.directives.some(Jo)&&(i.data.show=!0),u&&u.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,u)&&!he(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var f=u.data.transition=S({},s);if("out-in"===r)return this._leaving=!0,Wt(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Ko(t,o);if("in-out"===r){if(he(i))return l;var p,h=function(){p()};Wt(s,"afterEnter",h),Wt(s,"enterCancelled",h),Wt(f,"delayLeave",(function(t){p=t}))}}return o}}},Yo=S({tag:String,moveClass:String},Vo);function Qo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Zo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Yo.mode;var ei={Transition:Xo,TransitionGroup:{props:Yo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Wo(this),s=0;s-1?Er[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Er[t]=/HTMLUnknownElement/.test(e.toString())},S(Wn.options.directives,zo),S(Wn.options.components,ei),Wn.prototype.__patch__=G?Po:P,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=ht),Ze(t,"beforeMount"),r=function(){t._update(t._render(),n)},new Ve(t,r,P,{before:function(){t._isMounted&&!t._isDestroyed&&Ze(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),l=e&&e.path||"/",u=c.path?Ai(c.path,l,n||o.append):l,f=function(t,e,n){void 0===e&&(e={});var r,o=n||li;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(ci):ci(a)}return r}(c.query,o.query,r&&r.options.parseQuery),p=o.hash||c.hash;return p&&"#"!==p.charAt(0)&&(p="#"+p),{_normalized:!0,path:u,query:f,hash:p}}var zi,Vi=function(){},Hi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,s=o.href,c={},l=n.options.linkActiveClass,u=n.options.linkExactActiveClass,f=null==l?"router-link-active":l,p=null==u?"router-link-exact-active":u,h=null==this.activeClass?f:this.activeClass,d=null==this.exactActiveClass?p:this.exactActiveClass,v=a.redirectedFrom?pi(null,Ui(a.redirectedFrom),null,n):a;c[d]=Ei(r,v,this.exactPath),c[h]=this.exact||this.exactPath?c[d]:function(t,e){return 0===t.path.replace(fi,"/").indexOf(e.path.replace(fi,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,v);var m=c[d]?this.ariaCurrentValue:null,E=function(t){Wi(t)&&(e.replace?n.replace(i,Vi):n.push(i,Vi))},g={click:Wi};Array.isArray(this.event)?this.event.forEach((function(t){g[t]=E})):g[this.event]=E;var y={class:c},b=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:s,route:a,navigate:E,isActive:c[h],isExactActive:c[d]});if(b){if(1===b.length)return b[0];if(b.length>1||!b.length)return 0===b.length?t():t("span",{},b)}if("a"===this.tag)y.on=g,y.attrs={href:s,"aria-current":m};else{var _=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=qi(u.path,s.params),c(u,s,a)}if(s.path){s.params={};for(var h=0;h-1}function Ba(t,e){return Aa(t)&&t._isRouter&&(null==e||t.type===e)}function xa(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function wa(t){return function(e,n,r){var o=!1,i=0,a=null;Ca(t,(function(t,e,n,s){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var c,l=$a((function(e){var o;((o=e).__esModule||Oa&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zi.extend(e),n.components[s]=e,--i<=0&&r()})),u=$a((function(t){var e="Failed to resolve async component "+s+": "+t;a||(a=Aa(t)?t:new Error(e),r(a))}));try{c=t(l,u)}catch(t){u(t)}if(c)if("function"==typeof c.then)c.then(l,u);else{var f=c.component;f&&"function"==typeof f.then&&f.then(l,u)}}})),o||r()}}function Ca(t,e){return ka(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function ka(t){return Array.prototype.concat.apply([],t)}var Oa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function $a(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var ja=function(t,e){this.router=t,this.base=function(t){if(!t)if(Ki){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=di,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Sa(t,e,n,r){var o=Ca(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=zi.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return ka(r?o.reverse():o)}function Da(t,e){if(e)return function(){return t.apply(e,arguments)}}ja.prototype.listen=function(t){this.cb=t},ja.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},ja.prototype.onError=function(t){this.errorCbs.push(t)},ja.prototype.transitionTo=function(t,e,n){var r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(Ba(t,Ea.redirected)&&i===di||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},ja.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,s=function(t){!Ba(t)&&Aa(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},c=t.matched.length-1,l=o.matched.length-1;if(Ei(t,o)&&c===l&&t.matched[c]===o.matched[l])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),s(((a=ba(i=o,t,Ea.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var u=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=da&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Ta(t.base);t.current===di&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){va(Bi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){ma(Bi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ta(this.base)!==this.current.fullPath){var e=Bi(this.base+this.current.fullPath);t?va(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ta(this.base)},e}(ja);function Ta(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(Bi(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var La=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Ta(t);if(!/^\/#/.test(e))return window.location.replace(Bi(t+"/#"+e)),!0}(this.base)||Fa()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=da&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;Fa()&&t.transitionTo(Ra(),(function(r){n&&ia(t.router,r,e,!0),da||Na(r.fullPath)}))},o=da?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Ia(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ra()!==e&&(t?Ia(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ra()},e}(ja);function Fa(){var t=Ra();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ra(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ma(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ia(t){da?va(Ma(t)):window.location.hash=t}function Na(t){da?ma(Ma(t)):window.location.replace(Ma(t))}var qa=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){Ba(t,Ea.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(ja),Ua=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xi(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!da&&!1!==t.fallback,this.fallback&&(e="hash"),Ki||(e="abstract"),this.mode=e,e){case"history":this.history=new Pa(this,t.base);break;case"hash":this.history=new La(this,t.base,this.fallback);break;case"abstract":this.history=new qa(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Ua.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Ua.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Pa||n instanceof La){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;da&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ua.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Ua.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Ua.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Ua.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ua.prototype.onError=function(t){this.history.onError(t)},Ua.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Ua.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ua.prototype.go=function(t){this.history.go(t)},Ua.prototype.back=function(){this.go(-1)},Ua.prototype.forward=function(){this.go(1)},Ua.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ua.prototype.resolve=function(t,e,n){var r=Ui(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?Bi(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Ua.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ua.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==di&&this.history.transitionTo(this.history.getCurrentLocation())},Ua.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==di&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ua.prototype,za);var Va=Ua;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ua.install=function t(e){if(!t.installed||zi!==e){t.installed=!0,zi=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",bi),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Ua.version="3.6.5",Ua.isNavigationFailure=Ba,Ua.NavigationFailureType=Ea,Ua.START_LOCATION=di,Ki&&window.Vue&&window.Vue.use(Ua);n(94);n(90),n(126);var Wa={NotFound:()=>n.e(9).then(n.bind(null,281)),Layout:()=>Promise.all([n.e(0),n.e(2)]).then(n.bind(null,280))},Ka={"v-1151045e":()=>n.e(10).then(n.bind(null,284)),"v-7687dbe3":()=>n.e(12).then(n.bind(null,285)),"v-7ade593d":()=>n.e(13).then(n.bind(null,286)),"v-06e226fd":()=>n.e(11).then(n.bind(null,287)),"v-6c043199":()=>n.e(16).then(n.bind(null,288)),"v-49ed32b8":()=>n.e(18).then(n.bind(null,289)),"v-07d72cc6":()=>n.e(17).then(n.bind(null,290)),"v-a2e60fe0":()=>n.e(19).then(n.bind(null,291)),"v-c0e295c2":()=>n.e(7).then(n.bind(null,292)),"v-700b7892":()=>n.e(23).then(n.bind(null,293)),"v-97ff7a9a":()=>n.e(24).then(n.bind(null,294)),"v-7e84bb17":()=>n.e(25).then(n.bind(null,295)),"v-b799f18e":()=>n.e(22).then(n.bind(null,296)),"v-b48601fc":()=>n.e(26).then(n.bind(null,297)),"v-1d6c8203":()=>n.e(28).then(n.bind(null,298)),"v-3b4a094a":()=>n.e(15).then(n.bind(null,299)),"v-6aee24e3":()=>n.e(30).then(n.bind(null,300)),"v-206a88f7":()=>n.e(14).then(n.bind(null,301)),"v-4642376c":()=>n.e(31).then(n.bind(null,302)),"v-5d96c30f":()=>n.e(20).then(n.bind(null,303)),"v-a7970784":()=>n.e(32).then(n.bind(null,304)),"v-9c39d86e":()=>n.e(33).then(n.bind(null,305)),"v-6d10ef40":()=>n.e(27).then(n.bind(null,306)),"v-1fb25314":()=>n.e(37).then(n.bind(null,307)),"v-51ee3d19":()=>n.e(21).then(n.bind(null,308)),"v-afd7a946":()=>n.e(29).then(n.bind(null,309)),"v-4d08fff8":()=>n.e(35).then(n.bind(null,310)),"v-14f016fd":()=>n.e(34).then(n.bind(null,311)),"v-74c62ac8":()=>n.e(39).then(n.bind(null,312)),"v-031526f1":()=>n.e(42).then(n.bind(null,313)),"v-2c4163e0":()=>n.e(41).then(n.bind(null,314)),"v-19857dfe":()=>n.e(36).then(n.bind(null,315)),"v-54898c6d":()=>n.e(40).then(n.bind(null,316)),"v-995c65a0":()=>n.e(43).then(n.bind(null,317)),"v-4c42f052":()=>n.e(38).then(n.bind(null,318)),"v-0b603d28":()=>n.e(45).then(n.bind(null,319)),"v-644d0f52":()=>n.e(47).then(n.bind(null,320)),"v-915ccd2a":()=>n.e(46).then(n.bind(null,321)),"v-3289f112":()=>n.e(8).then(n.bind(null,322)),"v-19618f9e":()=>n.e(44).then(n.bind(null,323)),"v-b7c30ce4":()=>n.e(6).then(n.bind(null,324))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Ja=/-(\w)/g,Xa=Ga(t=>t.replace(Ja,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Qa=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Za=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function ts(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Za(Xa(e))):t(Za(e))||t(Qa(e))}const es=Object.assign({},Wa,Ka),ns=t=>es[t],rs=t=>Ka[t],os=t=>Wa[t],is=t=>Wn.component(t);function as(t){return ts(rs,t)}function ss(t){return ts(os,t)}function cs(t){return ts(ns,t)}function ls(t){return ts(is,t)}function us(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!ls(t)&&cs(t)){const e=await cs(t)();Wn.component(t,e.default)}}))}function fs(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var ps=n(87),hs=n.n(ps),ds=n(88),vs=n.n(ds),ms={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${vs()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=gs(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=ys(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return hs()([{name:"description",content:this.$description}],t,this.siteMeta,bs)},updateCanonicalLink(){Es(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",gs(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){ys(null,this.currentMetaTags),Es()}};function Es(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function gs(t=""){return t?``:""}function ys(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function bs(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var _s=n(89),As={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(_s)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Bs=n(22),xs=n.n(Bs),ws=[ms,As,{mounted(){xs.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Wn.component(t.name)||xs.a.start(),n()}),this.$router.afterEach(()=>{xs.a.done(),this.isSidebarOpen=!1})}}],Cs={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return fs("layout",t),Wn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},ks=n(14),Os=Object(ks.a)(Cs,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Os,"mixins",ws);const $s=[{name:"v-1151045e",path:"/",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1151045e").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-7687dbe3",path:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7687dbe3").then(n)}},{path:"/advance/5.2.组合注解.html",redirect:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html"},{path:"/advance/5.2.组合注解.html",redirect:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html"},{name:"v-7ade593d",path:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7ade593d").then(n)}},{path:"/advance/5.3.容器的生命周期回调.html",redirect:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html"},{path:"/advance/5.3.容器的生命周期回调.html",redirect:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html"},{name:"v-06e226fd",path:"/advance/5.1.%E7%BC%93%E5%AD%98.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-06e226fd").then(n)}},{path:"/advance/5.1.缓存.html",redirect:"/advance/5.1.%E7%BC%93%E5%AD%98.html"},{path:"/advance/5.1.缓存.html",redirect:"/advance/5.1.%E7%BC%93%E5%AD%98.html"},{name:"v-6c043199",path:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6c043199").then(n)}},{path:"/advance/5.6.类型转换.html",redirect:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html"},{path:"/advance/5.6.类型转换.html",redirect:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html"},{name:"v-49ed32b8",path:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-49ed32b8").then(n)}},{path:"/basic/1.4.常见问题.html",redirect:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html"},{path:"/basic/1.4.常见问题.html",redirect:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html"},{name:"v-07d72cc6",path:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-07d72cc6").then(n)}},{path:"/basic/1.3.配置文件.html",redirect:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html"},{path:"/basic/1.3.配置文件.html",redirect:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html"},{name:"v-a2e60fe0",path:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-a2e60fe0").then(n)}},{path:"/basic/quickstart/1.2.0.快速开始.html",redirect:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html"},{path:"/basic/quickstart/1.2.0.快速开始.html",redirect:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html"},{name:"v-c0e295c2",path:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-c0e295c2").then(n)}},{path:"/basic/1.1.用户指南.html",redirect:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html"},{path:"/basic/1.1.用户指南.html",redirect:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html"},{name:"v-700b7892",path:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-700b7892").then(n)}},{path:"/container/2.0.数据源容器.html",redirect:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.0.数据源容器.html",redirect:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html"},{name:"v-97ff7a9a",path:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-97ff7a9a").then(n)}},{path:"/container/2.1.本地缓存容器.html",redirect:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.1.本地缓存容器.html",redirect:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html"},{name:"v-7e84bb17",path:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-7e84bb17").then(n)}},{path:"/container/2.2.枚举容器.html",redirect:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.2.枚举容器.html",redirect:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html"},{name:"v-b799f18e",path:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b799f18e").then(n)}},{path:"/basic/quickstart/1.2.3.在springboot项目中使用.html",redirect:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.3.在springboot项目中使用.html",redirect:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-b48601fc",path:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b48601fc").then(n)}},{path:"/container/2.3.常量容器.html",redirect:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.3.常量容器.html",redirect:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html"},{name:"v-1d6c8203",path:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1d6c8203").then(n)}},{path:"/container/2.5.方法容器.html",redirect:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.5.方法容器.html",redirect:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html"},{name:"v-3b4a094a",path:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-3b4a094a").then(n)}},{path:"/advance/5.5.操作注解解析器.html",redirect:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{path:"/advance/5.5.操作注解解析器.html",redirect:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{name:"v-6aee24e3",path:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6aee24e3").then(n)}},{path:"/container/2.7.自定义容器.html",redirect:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.7.自定义容器.html",redirect:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html"},{name:"v-206a88f7",path:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-206a88f7").then(n)}},{path:"/advance/5.4.反射工厂.html",redirect:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html"},{path:"/advance/5.4.反射工厂.html",redirect:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html"},{name:"v-4642376c",path:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4642376c").then(n)}},{path:"/container/2.8.容器提供者.html",redirect:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html"},{path:"/container/2.8.容器提供者.html",redirect:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html"},{name:"v-5d96c30f",path:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-5d96c30f").then(n)}},{path:"/basic/quickstart/1.2.1.在非spring项目中使用.html",redirect:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.1.在非spring项目中使用.html",redirect:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-a7970784",path:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-a7970784").then(n)}},{path:"/container/2.9.对象容器.html",redirect:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.9.对象容器.html",redirect:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html"},{name:"v-9c39d86e",path:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-9c39d86e").then(n)}},{path:"/development/配置解析器.html",redirect:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{path:"/development/配置解析器.html",redirect:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html"},{name:"v-6d10ef40",path:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-6d10ef40").then(n)}},{path:"/container/2.4.lambda容器.html",redirect:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html"},{path:"/container/2.4.lambda容器.html",redirect:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html"},{name:"v-1fb25314",path:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-1fb25314").then(n)}},{path:"/extension/6.1.MybatisPlus扩展.html",redirect:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html"},{path:"/extension/6.1.MybatisPlus扩展.html",redirect:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html"},{name:"v-51ee3d19",path:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-51ee3d19").then(n)}},{path:"/basic/quickstart/1.2.2.在spring项目中使用.html",redirect:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{path:"/basic/quickstart/1.2.2.在spring项目中使用.html",redirect:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html"},{name:"v-afd7a946",path:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-afd7a946").then(n)}},{path:"/container/2.6.对象内省.html",redirect:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html"},{path:"/container/2.6.对象内省.html",redirect:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html"},{name:"v-4d08fff8",path:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4d08fff8").then(n)}},{path:"/execute/4.2.自动填充.html",redirect:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{path:"/execute/4.2.自动填充.html",redirect:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{name:"v-14f016fd",path:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-14f016fd").then(n)}},{path:"/execute/4.1.手动填充.html",redirect:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{path:"/execute/4.1.手动填充.html",redirect:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html"},{name:"v-74c62ac8",path:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-74c62ac8").then(n)}},{path:"/operation/3.1.声明装配操作.html",redirect:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html"},{path:"/operation/3.1.声明装配操作.html",redirect:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html"},{name:"v-031526f1",path:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-031526f1").then(n)}},{path:"/operation/3.4.拆卸嵌套对象.html",redirect:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html"},{path:"/operation/3.4.拆卸嵌套对象.html",redirect:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html"},{name:"v-2c4163e0",path:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-2c4163e0").then(n)}},{path:"/operation/3.3.指定装配处理器.html",redirect:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html"},{path:"/operation/3.3.指定装配处理器.html",redirect:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html"},{name:"v-19857dfe",path:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-19857dfe").then(n)}},{path:"/execute/4.3.操作执行器.html",redirect:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html"},{path:"/execute/4.3.操作执行器.html",redirect:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html"},{name:"v-54898c6d",path:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-54898c6d").then(n)}},{path:"/operation/3.2.配置属性映射.html",redirect:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html"},{path:"/operation/3.2.配置属性映射.html",redirect:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html"},{name:"v-995c65a0",path:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-995c65a0").then(n)}},{path:"/operation/3.5.操作分组.html",redirect:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html"},{path:"/operation/3.5.操作分组.html",redirect:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html"},{name:"v-4c42f052",path:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-4c42f052").then(n)}},{path:"/operation/3.0.操作配置.html",redirect:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html"},{path:"/operation/3.0.操作配置.html",redirect:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html"},{name:"v-0b603d28",path:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-0b603d28").then(n)}},{path:"/operation/3.7.操作者接口.html",redirect:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html"},{path:"/operation/3.7.操作者接口.html",redirect:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html"},{name:"v-644d0f52",path:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-644d0f52").then(n)}},{path:"/other/更新日志.html",redirect:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html"},{path:"/other/更新日志.html",redirect:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html"},{name:"v-915ccd2a",path:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-915ccd2a").then(n)}},{path:"/other/提问的智慧.html",redirect:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html"},{path:"/other/提问的智慧.html",redirect:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html"},{name:"v-3289f112",path:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-3289f112").then(n)}},{path:"/other/源码设计.html",redirect:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html"},{path:"/other/源码设计.html",redirect:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html"},{name:"v-19618f9e",path:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-19618f9e").then(n)}},{path:"/operation/3.6.操作排序.html",redirect:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html"},{path:"/operation/3.6.操作排序.html",redirect:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html"},{name:"v-b7c30ce4",path:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html",component:Os,beforeEnter:(t,e,n)=>{us("Layout","v-b7c30ce4").then(n)}},{path:"/other/联系作者.html",redirect:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"},{path:"/other/联系作者.html",redirect:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"},{path:"*",component:Os}],js={title:"Crane4j",description:"Crane4j, 基于注解的数据关联框架",base:"/crane4j/",headTags:[["link",{rel:"icon",href:"CRANE4J_ICON.png"}]],pages:[{title:"Home",frontmatter:{home:!0,heroImage:"./image-20230220150040070.png",heroText:null,tagline:"强大又好用的数据填充框架~",actionText:"快速上手 →",actionLink:"./basic/1.1.用户指南.md",features:[{title:"开箱即用",details:"结合 springboot 自动装配,一行注解即可启用框架功能,避免繁琐的基本配置"},{title:"上手简单",details:"简单好懂的 API 和全面的注解配置支持,助你轻松上手"},{title:"轻松扩展",details:"结合 spring 依赖注入,轻松替换默认组件,丝滑接入自定义逻辑"},{title:"适用于多种场景",details:"支持分组或嵌套填充,也支持一对多或多对多批量填充,操作粒度最细可到每一个字段"},{title:"丰富的数据源支持",details:"默认即支持字典、枚举、常量类以及可执行方法等类型数据源,简单操作即可扩展更多数据源"},{title:"强大的扩展功能",details:"提供自动填充,多线程填充,缓存、动态表达式等扩展功能,还支持 mybatis-plus 等扩展插件"}]},regularPath:"/",relativePath:"README.md",key:"v-1151045e",path:"/"},{title:"组合注解",frontmatter:{},regularPath:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",relativePath:"advance/5.2.组合注解.md",key:"v-7687dbe3",path:"/advance/5.2.%E7%BB%84%E5%90%88%E6%B3%A8%E8%A7%A3.html",headers:[{level:2,title:"组合注解",slug:"组合注解"}]},{title:"5.3.1.容器生命周期处理器",frontmatter:{},regularPath:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",relativePath:"advance/5.3.容器的生命周期回调.md",key:"v-7ade593d",path:"/advance/5.3.%E5%AE%B9%E5%99%A8%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%9E%E8%B0%83.html",headers:[{level:2,title:"5.3.1.容器生命周期处理器",slug:"_5-3-1-容器生命周期处理器"},{level:2,title:"5.3.2.容器的生命周期回调",slug:"_5-3-2-容器的生命周期回调"}]},{title:"概述",frontmatter:{},regularPath:"/advance/5.1.%E7%BC%93%E5%AD%98.html",relativePath:"advance/5.1.缓存.md",key:"v-06e226fd",path:"/advance/5.1.%E7%BC%93%E5%AD%98.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"5.1.1.缓存管理器",slug:"_5-1-1-缓存管理器"},{level:2,title:"5.1.2.结合数据源容器使用",slug:"_5-1-2-结合数据源容器使用"},{level:2,title:"5.1.3.配置缓存容器",slug:"_5-1-3-配置缓存容器"},{level:3,title:"5.1.3.1. 手动替换",slug:"_5-1-3-1-手动替换"},{level:3,title:"5.1.3.2. 添加注解",slug:"_5-1-3-2-添加注解"},{level:3,title:"5.1.3.3. 配置文件",slug:"_5-1-3-3-配置文件"}]},{title:"类型转换",frontmatter:{},regularPath:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",relativePath:"advance/5.6.类型转换.md",key:"v-6c043199",path:"/advance/5.6.%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.html",headers:[{level:2,title:"类型转换",slug:"类型转换"}]},{title:"1、填充不生效?",frontmatter:{},regularPath:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",relativePath:"basic/1.4.常见问题.md",key:"v-49ed32b8",path:"/basic/1.4.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.html",headers:[{level:2,title:"1、填充不生效?",slug:"_1、填充不生效"},{level:2,title:"2、如何实现嵌套填充?",slug:"_2、如何实现嵌套填充"},{level:2,title:"3、如何实现级联填充?",slug:"_3、如何实现级联填充"},{level:2,title:"4、如何处理一对多的情况?",slug:"_4、如何处理一对多的情况"},{level:2,title:"5、键字段可以是按分隔符拼接的字符串吗?",slug:"_5、键字段可以是按分隔符拼接的字符串吗"},{level:2,title:"6、键字段可以是集合或者数组吗?",slug:"_6、键字段可以是集合或者数组吗"},{level:2,title:"7、为什么使用异步执行器的时候报错?",slug:"_7、为什么使用异步执行器的时候报错"},{level:2,title:"8、怎么刷新容器的数据 ?",slug:"_8、怎么刷新容器的数据"},{level:2,title:"9、怎么忽略掉某些字段不进行填充?",slug:"_9、怎么忽略掉某些字段不进行填充"},{level:2,title:"10、为什么 @ContainerMethod 注解不生效?",slug:"_10、为什么-containermethod-注解不生效"},{level:2,title:"11、为什么 @AutoOperate 注解不生效?",slug:"_11、为什么-autooperate-注解不生效"},{level:2,title:"12、为什么引了 guava 和 hutool ?",slug:"_12、为什么引了-guava-和-hutool"},{level:2,title:"13、支持 jdk9+ / springboot3 吗?",slug:"_13、支持-jdk9-springboot3-吗"},{level:2,title:"14、容器可以做一些自定义的初始化/销毁操作吗?",slug:"_14、容器可以做一些自定义的初始化-销毁操作吗"},{level:2,title:"15、可以支持同时根据多个 key 字段填充数据吗?",slug:"_15、可以支持同时根据多个-key-字段填充数据吗"}]},{frontmatter:{},regularPath:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",relativePath:"basic/1.3.配置文件.md",key:"v-07d72cc6",path:"/basic/1.3.%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",headers:[{level:2,title:"1.3.1.反射",slug:"_1-3-1-反射"},{level:3,title:"1.3.1.1.是否启用字节码反射",slug:"_1-3-1-1-是否启用字节码反射"},{level:3,title:"1.3.1.2.是否支持处理Map对象",slug:"_1-3-1-2-是否支持处理map对象"},{level:3,title:"1.3.1.3.是否支持链式操作符",slug:"_1-3-1-3-是否支持链式操作符"},{level:2,title:"1.3.2.容器",slug:"_1-3-2-容器"},{level:3,title:"1.3.2.1.扫描常量容器",slug:"_1-3-2-1-扫描常量容器"},{level:3,title:"1.3.2.2.扫描枚举容器",slug:"_1-3-2-2-扫描枚举容器"},{level:3,title:"1.3.2.3.扫描方法容器",slug:"_1-3-2-3-扫描方法容器"},{level:3,title:"1.3.2.4.容器缓存配置",slug:"_1-3-2-4-容器缓存配置"},{level:2,title:"1.3.3.自动填充",slug:"_1-3-3-自动填充"},{level:2,title:"1.3.4.操作配置预解析",slug:"_1-3-4-操作配置预解析"}]},{title:"快速开始",frontmatter:{},regularPath:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",relativePath:"basic/quickstart/1.2.0.快速开始.md",key:"v-a2e60fe0",path:"/basic/quickstart/1.2.0.%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.html",headers:[{level:2,title:"快速开始",slug:"快速开始"}]},{frontmatter:{},regularPath:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",relativePath:"basic/1.1.用户指南.md",key:"v-c0e295c2",path:"/basic/1.1.%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.html",headers:[{level:2,title:"1.1.1.为什么写?",slug:"_1-1-1-为什么写"},{level:2,title:"1.1.2.它解决了什么问题?",slug:"_1-1-2-它解决了什么问题"},{level:2,title:"1.1.3.它有什么特性?",slug:"_1-1-3-它有什么特性"},{level:2,title:"1.1.4.如何使用?",slug:"_1-1-4-如何使用"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.0.数据源容器.md",key:"v-700b7892",path:"/container/2.0.%E6%95%B0%E6%8D%AE%E6%BA%90%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.0.1.默认实现",slug:"_2-0-1-默认实现"},{level:2,title:"2.0.2.注册容器",slug:"_2-0-2-注册容器"}]},{title:"本地缓存容器",frontmatter:{},regularPath:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.1.本地缓存容器.md",key:"v-97ff7a9a",path:"/container/2.1.%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"本地缓存容器",slug:"本地缓存容器"}]},{title:"2.2.1. 基本使用",frontmatter:{},regularPath:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.2.枚举容器.md",key:"v-7e84bb17",path:"/container/2.2.%E6%9E%9A%E4%B8%BE%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"2.2.1. 基本使用",slug:"_2-2-1-基本使用"},{level:2,title:"2.2.2. 可选注解",slug:"_2-2-2-可选注解"},{level:2,title:"2.2.3.枚举装配",slug:"_2-2-3-枚举装配"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.3.在springboot项目中使用.md",key:"v-b799f18e",path:"/basic/quickstart/1.2.3.%E5%9C%A8springboot%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:2,title:"使用",slug:"使用"}]},{title:"2.3.1. 基本使用",frontmatter:{},regularPath:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.3.常量容器.md",key:"v-b48601fc",path:"/container/2.3.%E5%B8%B8%E9%87%8F%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"2.3.1. 基本使用",slug:"_2-3-1-基本使用"},{level:2,title:"2.3.2. 可选注解",slug:"_2-3-2-可选注解"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.5.方法容器.md",key:"v-1d6c8203",path:"/container/2.5.%E6%96%B9%E6%B3%95%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.5.1.声明方法数据源",slug:"_2-5-1-声明方法数据源"},{level:2,title:"2.5.2.对结果分组",slug:"_2-5-2-对结果分组"},{level:3,title:"2.5.2.1.一对一",slug:"_2-5-2-1-一对一"},{level:3,title:"2.5.2.2.一对多",slug:"_2-5-2-2-一对多"},{level:3,title:"2.5.2.3.不分组",slug:"_2-5-2-3-不分组"},{level:2,title:"2.5.4.数据源容器工厂",slug:"_2-5-4-数据源容器工厂"},{level:2,title:"2.5.5.注册方法数据源容器",slug:"_2-5-5-注册方法数据源容器"}]},{title:"操作注解解析器",frontmatter:{},regularPath:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",relativePath:"advance/5.5.操作注解解析器.md",key:"v-3b4a094a",path:"/advance/5.5.%E6%93%8D%E4%BD%9C%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90%E5%99%A8.html",headers:[{level:2,title:"操作注解解析器",slug:"操作注解解析器"}]},{title:"自定义容器",frontmatter:{},regularPath:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.7.自定义容器.md",key:"v-6aee24e3",path:"/container/2.7.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"自定义容器",slug:"自定义容器"}]},{title:"反射工厂",frontmatter:{},regularPath:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",relativePath:"advance/5.4.反射工厂.md",key:"v-206a88f7",path:"/advance/5.4.%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82.html",headers:[{level:2,title:"反射工厂",slug:"反射工厂"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",relativePath:"container/2.8.容器提供者.md",key:"v-4642376c",path:"/container/2.8.%E5%AE%B9%E5%99%A8%E6%8F%90%E4%BE%9B%E8%80%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"2.8.1.注册",slug:"_2-8-1-注册"},{level:2,title:"2.8.2.使用",slug:"_2-8-2-使用"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.1.在非spring项目中使用.md",key:"v-5d96c30f",path:"/basic/quickstart/1.2.1.%E5%9C%A8%E9%9D%9Espring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:3,title:"引入依赖",slug:"引入依赖"},{level:3,title:"全局配置",slug:"全局配置"},{level:3,title:"启用填充工具",slug:"启用填充工具"},{level:3,title:"启用扩展功能",slug:"启用扩展功能"},{level:2,title:"配置数据源",slug:"配置数据源"},{level:2,title:"配置装配操作",slug:"配置装配操作"},{level:2,title:"执行装配操作",slug:"执行装配操作"},{level:2,title:"执行嵌套填充",slug:"执行嵌套填充"}]},{title:"概述",frontmatter:{},regularPath:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.9.对象容器.md",key:"v-a7970784",path:"/container/2.9.%E5%AF%B9%E8%B1%A1%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"使用",slug:"使用"}]},{title:"一、什么是配置解析器",frontmatter:{},regularPath:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",relativePath:"development/配置解析器.md",key:"v-9c39d86e",path:"/development/%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%99%A8.html",headers:[{level:2,title:"一、什么是配置解析器",slug:"一、什么是配置解析器"},{level:2,title:"二、运行流程",slug:"二、运行流程"},{level:2,title:"三、不同版本的实现",slug:"三、不同版本的实现"},{level:3,title:"1、crane 时期",slug:"_1、crane-时期"},{level:3,title:"2、v1.0 - 1.2",slug:"_2、v1-0-1-2"},{level:3,title:"3、v1.3",slug:"_3、v1-3"},{level:3,title:"4、v2.0",slug:"_4、v2-0"},{level:2,title:"四、优化和调试",slug:"四、优化和调试"},{level:3,title:"1、可以打断点的关键方法",slug:"_1、可以打断点的关键方法"},{level:3,title:"2、可以优化的地方",slug:"_2、可以优化的地方"}]},{title:"Lambda容器",frontmatter:{},regularPath:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",relativePath:"container/2.4.lambda容器.md",key:"v-6d10ef40",path:"/container/2.4.lambda%E5%AE%B9%E5%99%A8.html",headers:[{level:2,title:"Lambda容器",slug:"lambda容器"}]},{title:"概述",frontmatter:{},regularPath:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",relativePath:"extension/6.1.MybatisPlus扩展.md",key:"v-1fb25314",path:"/extension/6.1.MybatisPlus%E6%89%A9%E5%B1%95.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"6.1.1.安装",slug:"_6-1-1-安装"},{level:2,title:"6.1.2.注册Mapper",slug:"_6-1-2-注册mapper"},{level:2,title:"6.1.3.基本使用",slug:"_6-1-3-基本使用"},{level:3,title:"6.1.3.1.根据主键查询全部字段",slug:"_6-1-3-1-根据主键查询全部字段"},{level:3,title:"6.1.3.2.根据主键查询指定字段",slug:"_6-1-3-2-根据主键查询指定字段"},{level:3,title:"6.1.3.3.根据指定外键查询全部字段",slug:"_6-1-3-3-根据指定外键查询全部字段"},{level:3,title:"6.1.3.4.根据指定外键查询指定字段",slug:"_6-1-3-4-根据指定外键查询指定字段"},{level:2,title:"6.1.4.指定查询字段 SQL",slug:"_6-1-4-指定查询字段-sql"},{level:2,title:"6.1.5.指定映射类型",slug:"_6-1-5-指定映射类型"}]},{title:"安装",frontmatter:{},regularPath:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",relativePath:"basic/quickstart/1.2.2.在spring项目中使用.md",key:"v-51ee3d19",path:"/basic/quickstart/1.2.2.%E5%9C%A8spring%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8.html",headers:[{level:2,title:"安装",slug:"安装"},{level:3,title:"引入依赖",slug:"引入依赖"},{level:3,title:"启用配置",slug:"启用配置"},{level:2,title:"配置数据源",slug:"配置数据源"},{level:2,title:"配置装配操作",slug:"配置装配操作"},{level:2,title:"执行装配操作",slug:"执行装配操作"},{level:2,title:"执行嵌套填充",slug:"执行嵌套填充"}]},{title:"对象内省",frontmatter:{},regularPath:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",relativePath:"container/2.6.对象内省.md",key:"v-afd7a946",path:"/container/2.6.%E5%AF%B9%E8%B1%A1%E5%86%85%E7%9C%81.html",headers:[{level:2,title:"对象内省",slug:"对象内省"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",relativePath:"execute/4.2.自动填充.md",key:"v-4d08fff8",path:"/execute/4.2.%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.2.1.填充方法返回值",slug:"_4-2-1-填充方法返回值"},{level:2,title:"4.2.2.自动填充方法参数",slug:"_4-2-2-自动填充方法参数"},{level:2,title:"4.2.3.自动类型推断",slug:"_4-2-3-自动类型推断"},{level:2,title:"4.2.4.包装类提取",slug:"_4-2-4-包装类提取"},{level:2,title:"4.2.5.应用条件表达式",slug:"_4-2-5-应用条件表达式"},{level:2,title:"4.2.6.分组填充",slug:"_4-2-6-分组填充"},{level:2,title:"4.2.7.指定执行器",slug:"_4-2-7-指定执行器"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",relativePath:"execute/4.1.手动填充.md",key:"v-14f016fd",path:"/execute/4.1.%E6%89%8B%E5%8A%A8%E5%A1%AB%E5%85%85.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.1.1.使用执行器手动填充",slug:"_4-1-1-使用执行器手动填充"},{level:2,title:"4.1.2.使用 OperateTemplate",slug:"_4-1-2-使用-operatetemplate"}]},{title:"3.1.1.在属性上声明",frontmatter:{},regularPath:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",relativePath:"operation/3.1.声明装配操作.md",key:"v-74c62ac8",path:"/operation/3.1.%E5%A3%B0%E6%98%8E%E8%A3%85%E9%85%8D%E6%93%8D%E4%BD%9C.html",headers:[{level:2,title:"3.1.1.在属性上声明",slug:"_3-1-1-在属性上声明"},{level:2,title:"3.1.2.在类上声明",slug:"_3-1-2-在类上声明"},{level:2,title:"3.1.3.声明多个操作",slug:"_3-1-3-声明多个操作"},{level:2,title:"3.1.4.动态的表达式",slug:"_3-1-4-动态的表达式"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",relativePath:"operation/3.4.拆卸嵌套对象.md",key:"v-031526f1",path:"/operation/3.4.%E6%8B%86%E5%8D%B8%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.4.1.在属性上声明",slug:"_3-4-1-在属性上声明"},{level:2,title:"3.4.2.在类上声明",slug:"_3-4-2-在类上声明"},{level:2,title:"3.4.3.自动类型推断",slug:"_3-4-3-自动类型推断"},{level:2,title:"3.4.4.拆卸操作处理器",slug:"_3-4-4-拆卸操作处理器"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",relativePath:"operation/3.3.指定装配处理器.md",key:"v-2c4163e0",path:"/operation/3.3.%E6%8C%87%E5%AE%9A%E8%A3%85%E9%85%8D%E5%A4%84%E7%90%86%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.2.1.使用",slug:"_3-2-1-使用"},{level:2,title:"3.2.2.一对多装配",slug:"_3-2-2-一对多装配"},{level:2,title:"3.2.3.多对多装配",slug:"_3-2-3-多对多装配"}]},{title:"概述",frontmatter:{},regularPath:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",relativePath:"execute/4.3.操作执行器.md",key:"v-19857dfe",path:"/execute/4.3.%E6%93%8D%E4%BD%9C%E6%89%A7%E8%A1%8C%E5%99%A8.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"4.3.1.可选实现",slug:"_4-3-1-可选实现"},{level:2,title:"4.3.2.使用",slug:"_4-3-2-使用"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",relativePath:"operation/3.2.配置属性映射.md",key:"v-54898c6d",path:"/operation/3.2.%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%98%A0%E5%B0%84.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.2.1.将属性映射到属性",slug:"_3-2-1-将属性映射到属性"},{level:2,title:"3.2.2.将对象映射到属性",slug:"_3-2-2-将对象映射到属性"},{level:2,title:"3.2.3.将值映射到键属性",slug:"_3-2-3-将值映射到键属性"},{level:2,title:"3.2.4.批量映射",slug:"_3-2-4-批量映射"},{level:2,title:"3.2.5.映射模板",slug:"_3-2-5-映射模板"},{level:2,title:"3.2.6.链式操作符",slug:"_3-2-6-链式操作符"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",relativePath:"operation/3.5.操作分组.md",key:"v-995c65a0",path:"/operation/3.5.%E6%93%8D%E4%BD%9C%E5%88%86%E7%BB%84.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.5.1.为操作分组",slug:"_3-5-1-为操作分组"},{level:2,title:"3.5.2.按分组规则执行操作",slug:"_3-5-2-按分组规则执行操作"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",relativePath:"operation/3.0.操作配置.md",key:"v-4c42f052",path:"/operation/3.0.%E6%93%8D%E4%BD%9C%E9%85%8D%E7%BD%AE.html",headers:[{level:2,title:"概述",slug:"概述"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",relativePath:"operation/3.7.操作者接口.md",key:"v-0b603d28",path:"/operation/3.7.%E6%93%8D%E4%BD%9C%E8%80%85%E6%8E%A5%E5%8F%A3.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.7.1.基本使用",slug:"_3-7-1-基本使用"},{level:2,title:"3.7.2.在 Spring 中使用",slug:"_3-7-2-在-spring-中使用"},{level:2,title:"3.7.3.动态数据源容器",slug:"_3-7-3-动态数据源容器"},{level:3,title:"3.7.3.1.声明参数为容器",slug:"_3-7-3-1-声明参数为容器"},{level:3,title:"3.7.3.2.使用参数容器",slug:"_3-7-3-2-使用参数容器"},{level:3,title:"3.7.3.3.参数适配器",slug:"_3-7-3-3-参数适配器"},{level:2,title:"3.7.4.指定执行器和解析器",slug:"_3-7-4-指定执行器和解析器"},{level:2,title:"3.7.5.代理方法工厂",slug:"_3-7-5-代理方法工厂"}]},{title:"1.0.0 (2023-03-23)",frontmatter:{},regularPath:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",relativePath:"other/更新日志.md",key:"v-644d0f52",path:"/other/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.html",headers:[{level:2,title:"1.0.0 (2023-03-23)",slug:"_1-0-0-2023-03-23"},{level:2,title:"1.1.0 (2023-03-30)",slug:"_1-1-0-2023-03-30"},{level:2,title:"1.2.0 (2023-04-09)",slug:"_1-2-0-2023-04-09"},{level:2,title:"1.3.0-ALPHA (2023-05-10)",slug:"_1-3-0-alpha-2023-05-10"},{level:2,title:"2.0.0-ALPHA (2023-07-08)",slug:"_2-0-0-alpha-2023-07-08"},{level:2,title:"2.0.0-BATE (2023-07-30)",slug:"_2-0-0-bate-2023-07-30"}]},{frontmatter:{},regularPath:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",relativePath:"other/提问的智慧.md",key:"v-915ccd2a",path:"/other/%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7.html",headers:[{level:2,title:"在提问之前",slug:"在提问之前"},{level:2,title:"当你提问时",slug:"当你提问时"},{level:3,title:"慎选提问的论坛",slug:"慎选提问的论坛"},{level:3,title:"Stack Overflow",slug:"stack-overflow"},{level:3,title:"网站和 IRC 论坛",slug:"网站和-irc-论坛"},{level:3,title:"第二步,使用项目邮件列表",slug:"第二步-使用项目邮件列表"},{level:3,title:"使用有意义且描述明确的标题",slug:"使用有意义且描述明确的标题"},{level:3,title:"使问题容易回复",slug:"使问题容易回复"},{level:3,title:"",slug:"使用清晰、正确、精准且合乎语法的语句"},{level:3,title:"使用易于读取且标准的文件格式发送问题",slug:"使用易于读取且标准的文件格式发送问题"},{level:3,title:"精确地描述问题并言之有物",slug:"精确地描述问题并言之有物"},{level:3,title:"话不在多而在精",slug:"话不在多而在精"},{level:3,title:"别动辄声称找到 Bug",slug:"别动辄声称找到-bug"},{level:3,title:"低声下气不能代替你的功课",slug:"低声下气不能代替你的功课"},{level:3,title:"描述问题症状而非你的猜测",slug:"描述问题症状而非你的猜测"},{level:3,title:"按发生时间先后列出问题症状",slug:"按发生时间先后列出问题症状"},{level:3,title:"描述目标而不是过程",slug:"描述目标而不是过程"},{level:3,title:"别要求使用私人电邮回复",slug:"别要求使用私人电邮回复"},{level:3,title:"清楚明确地表达你的问题以及需求",slug:"清楚明确地表达你的问题以及需求"},{level:3,title:"询问有关代码的问题时",slug:"询问有关代码的问题时"},{level:3,title:"别把自己家庭作业的问题贴上来",slug:"别把自己家庭作业的问题贴上来"},{level:3,title:"去掉无意义的提问句",slug:"去掉无意义的提问句"},{level:3,title:"即使你很急也不要在标题写紧急",slug:"即使你很急也不要在标题写紧急"},{level:3,title:"礼多人不怪,而且有时还很有帮助",slug:"礼多人不怪-而且有时还很有帮助"},{level:3,title:"问题解决后,加个简短的补充说明",slug:"问题解决后-加个简短的补充说明"},{level:2,title:"如何解读答案",slug:"如何解读答案"},{level:3,title:"RTFM 和 STFW:如何知道你已完全搞砸了",slug:"rtfm-和-stfw-如何知道你已完全搞砸了"},{level:3,title:"如果还是搞不懂",slug:"如果还是搞不懂"},{level:3,title:"处理无礼的回应",slug:"处理无礼的回应"},{level:2,title:"如何避免扮演失败者",slug:"如何避免扮演失败者"},{level:2,title:"不该问的问题",slug:"不该问的问题"},{level:2,title:"好问题与蠢问题",slug:"好问题与蠢问题"},{level:2,title:"如果得不到回答",slug:"如果得不到回答"},{level:2,title:"如何更好地回答问题",slug:"如何更好地回答问题"},{level:2,title:"相关资源",slug:"相关资源"},{level:2,title:"鸣谢",slug:"鸣谢"}]},{title:"执行流程",frontmatter:{},regularPath:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",relativePath:"other/源码设计.md",key:"v-3289f112",path:"/other/%E6%BA%90%E7%A0%81%E8%AE%BE%E8%AE%A1.html",headers:[{level:2,title:"执行流程",slug:"执行流程"},{level:2,title:"操作配置 & 配置解析器",slug:"操作配置-配置解析器"},{level:2,title:"操作处理器 & 操作执行器",slug:"操作处理器-操作执行器"},{level:2,title:"数据源容器 & 属性映射",slug:"数据源容器-属性映射"},{level:2,title:"设计原则",slug:"设计原则"}]},{title:"概述",frontmatter:{},regularPath:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",relativePath:"operation/3.6.操作排序.md",key:"v-19618f9e",path:"/operation/3.6.%E6%93%8D%E4%BD%9C%E6%8E%92%E5%BA%8F.html",headers:[{level:2,title:"概述",slug:"概述"},{level:2,title:"3.6.1.指定排序值",slug:"_3-6-1-指定排序值"},{level:2,title:"3.6.2.按顺序执行",slug:"_3-6-2-按顺序执行"}]},{frontmatter:{},regularPath:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html",relativePath:"other/联系作者.md",key:"v-b7c30ce4",path:"/other/%E8%81%94%E7%B3%BB%E4%BD%9C%E8%80%85.html"}],themeConfig:{sidebarDepth:3,nav:[{text:"首页",link:"/"},{text:"源码",items:[{text:"GitHub",link:"https://github.com/opengoofy/crane4j"},{text:"Gitee",link:"https://gitee.com/CreateSequence/crane4j"}]},{text:"关于作者",items:[{text:"Github",link:"https://github.com/Createsequence/"},{text:"Gitee",link:"https://gitee.com/CreateSequence"},{text:"Blog",link:"https://blog.xiajibagao.top"}]},{text:"关于我们",link:"https://github.com/opengoofy"}],sidebar:[{title:"1.基础",collapsable:!1,children:[{title:"1.1.用户指南",path:"/basic/1.1.用户指南.md"},{title:"1.2.快速开始",path:"/basic/quickstart/1.2.0.快速开始.html",children:[{title:"1.2.1.在非spring项目中使用",path:"/basic/quickstart/1.2.1.在非spring项目中使用.md"},{title:"1.2.2.在spring项目中使用",path:"/basic/quickstart/1.2.2.在spring项目中使用.md"},{title:"1.2.3.在springboot项目中使用",path:"/basic/quickstart/1.2.3.在springboot项目中使用.md"}]},{title:"1.3.配置文件",path:"/basic/1.3.配置文件.md"},{title:"1.4.常见问题",path:"/basic/1.4.常见问题.md"}]},{title:"2.数据源容器",path:"/container/2.0.数据源容器.html",collapsable:!1,children:[{title:"2.1.本地缓存",path:"/container/2.1.本地缓存容器.md"},{title:"2.2.枚举",path:"/container/2.2.枚举容器.md"},{title:"2.3.常量",path:"/container/2.3.常量容器.md"},{title:"2.4.lambda表达式",path:"/container/2.4.lambda容器.md"},{title:"2.5.可调用方法",path:"/container/2.5.方法容器.md"},{title:"2.6.对象内省",path:"/container/2.6.对象内省.md"},{title:"2.7.接口/自定义",path:"/container/2.7.自定义容器.md"},{title:"2.8.容器提供者",path:"/container/2.8.容器提供者.md"},{title:"2.9.对象容器",path:"/container/2.9.对象容器.md"}]},{title:"3.操作配置",collapsable:!1,path:"/operation/3.0.操作配置.html",children:[{title:"3.1.声明装配操作",path:"/operation/3.1.声明装配操作.md"},{title:"3.2.配置属性映射",path:"/operation/3.2.配置属性映射.md"},{title:"3.3.指定装配处理器",path:"/operation/3.3.指定装配处理器.md"},{title:"3.4.拆卸嵌套对象",path:"/operation/3.4.拆卸嵌套对象.md"},{title:"3.5.操作分组",path:"/operation/3.5.操作分组.md"},{title:"3.6.操作排序",path:"/operation/3.6.操作排序.md"},{title:"3.7.操作者接口",path:"/operation/3.7.操作者接口.md"}]},{title:"4.执行操作",collapsable:!1,children:[{title:"4.1.手动填充",path:"/execute/4.1.手动填充.md"},{title:"4.2.自动填充",path:"/execute/4.2.自动填充.md"},{title:"4.3.操作执行器",path:"/execute/4.3.操作执行器.md"}]},{title:"5.高级特性",collapsable:!1,children:[{title:"5.1.缓存",path:"/advance/5.1.缓存.md"},{title:"5.2.组合注解",path:"/advance/5.2.组合注解.md"},{title:"5.3.容器的生命周期回调",path:"/advance/5.3.容器的生命周期回调.md"},{title:"5.4.反射工厂",path:"/advance/5.4.反射工厂.md"},{title:"5.5.操作注解解析器",path:"/advance/5.5.操作注解解析器.md"},{title:"5.5.类型转换",path:"/advance/5.6.类型转换.md"}]},{title:"6.扩展组件",collapsable:!1,children:[{title:"6.1.MybatisPlus扩展.md",path:"/extension/6.1.MybatisPlus扩展.md"}]},{title:"其他",collapsable:!1,children:[{title:"联系作者",path:"/other/联系作者.md"},{title:"提问的智慧",path:"/other/提问的智慧.md"},{title:"源码设计",path:"/other/源码设计.md"},{title:"更新日志",path:"/other/更新日志.md"}]}]}};n(234);Wn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,282))),Wn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,283))),Wn.component("Badge",()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,325)));n(235);var Ss=[{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{}],Ds=[];class Ps extends class{constructor(){this.store=new Wn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Wn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(Ps.prototype,{getPageAsyncComponent:as,getLayoutAsyncComponent:ss,getAsyncComponent:cs,getVueComponent:ls});var Ts={install(t){const e=new Ps;t.$vuepress=e,t.prototype.$vuepress=e}};function Ls(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var Fs={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return fs("pageKey",e),Wn.component(e)||Wn.component(e,as(e)),Wn.component(e)?t(e):t("")}},Rs={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},Ms={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Is=(n(236),n(237),Object(ks.a)(Ms,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Ns={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Wn.config.productionTip=!1,Wn.use(Va),Wn.use(Ts),Wn.mixin(function(t,e,n=Wn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Wn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Ls(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Ls(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Ls(t,o)?r(o):Ls(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(Ss.filter(t=>"function"==typeof t).map(e=>e({Vue:Wn,options:r,router:n,siteData:js,isServer:t})))}catch(t){console.error(t)}return{app:new Wn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},Ds.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file diff --git "a/docs/basic/1.1.\347\224\250\346\210\267\346\214\207\345\215\227.html" "b/docs/basic/1.1.\347\224\250\346\210\267\346\214\207\345\215\227.html" index ca8fe8c4..1fa3344e 100644 --- "a/docs/basic/1.1.\347\224\250\346\210\267\346\214\207\345\215\227.html" +++ "b/docs/basic/1.1.\347\224\250\346\210\267\346\214\207\345\215\227.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/basic/1.3.\351\205\215\347\275\256\346\226\207\344\273\266.html" "b/docs/basic/1.3.\351\205\215\347\275\256\346\226\207\344\273\266.html" index a6b1a7fb..05918e0c 100644 --- "a/docs/basic/1.3.\351\205\215\347\275\256\346\226\207\344\273\266.html" +++ "b/docs/basic/1.3.\351\205\215\347\275\256\346\226\207\344\273\266.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/basic/1.4.\345\270\270\350\247\201\351\227\256\351\242\230.html" "b/docs/basic/1.4.\345\270\270\350\247\201\351\227\256\351\242\230.html" index 3c6340f6..9e407453 100644 --- "a/docs/basic/1.4.\345\270\270\350\247\201\351\227\256\351\242\230.html" +++ "b/docs/basic/1.4.\345\270\270\350\247\201\351\227\256\351\242\230.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/basic/quickstart/1.2.0.\345\277\253\351\200\237\345\274\200\345\247\213.html" "b/docs/basic/quickstart/1.2.0.\345\277\253\351\200\237\345\274\200\345\247\213.html" index 7366e41d..20d5446f 100644 --- "a/docs/basic/quickstart/1.2.0.\345\277\253\351\200\237\345\274\200\345\247\213.html" +++ "b/docs/basic/quickstart/1.2.0.\345\277\253\351\200\237\345\274\200\345\247\213.html" @@ -8,8 +8,8 @@ - - + + - + diff --git "a/docs/basic/quickstart/1.2.1.\345\234\250\351\235\236spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" "b/docs/basic/quickstart/1.2.1.\345\234\250\351\235\236spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" index 57687c91..285cc1c0 100644 --- "a/docs/basic/quickstart/1.2.1.\345\234\250\351\235\236spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" +++ "b/docs/basic/quickstart/1.2.1.\345\234\250\351\235\236spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/basic/quickstart/1.2.2.\345\234\250spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" "b/docs/basic/quickstart/1.2.2.\345\234\250spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" index 90fb9173..a90fc7ca 100644 --- "a/docs/basic/quickstart/1.2.2.\345\234\250spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" +++ "b/docs/basic/quickstart/1.2.2.\345\234\250spring\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/basic/quickstart/1.2.3.\345\234\250springboot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" "b/docs/basic/quickstart/1.2.3.\345\234\250springboot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" index ef97bdd1..e09a7649 100644 --- "a/docs/basic/quickstart/1.2.3.\345\234\250springboot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" +++ "b/docs/basic/quickstart/1.2.3.\345\234\250springboot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.0.\346\225\260\346\215\256\346\272\220\345\256\271\345\231\250.html" "b/docs/container/2.0.\346\225\260\346\215\256\346\272\220\345\256\271\345\231\250.html" index 73c8f4d6..d29d56c5 100644 --- "a/docs/container/2.0.\346\225\260\346\215\256\346\272\220\345\256\271\345\231\250.html" +++ "b/docs/container/2.0.\346\225\260\346\215\256\346\272\220\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + + - + diff --git "a/docs/container/2.1.\346\234\254\345\234\260\347\274\223\345\255\230\345\256\271\345\231\250.html" "b/docs/container/2.1.\346\234\254\345\234\260\347\274\223\345\255\230\345\256\271\345\231\250.html" index 0645c4f7..0029fed4 100644 --- "a/docs/container/2.1.\346\234\254\345\234\260\347\274\223\345\255\230\345\256\271\345\231\250.html" +++ "b/docs/container/2.1.\346\234\254\345\234\260\347\274\223\345\255\230\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.2.\346\236\232\344\270\276\345\256\271\345\231\250.html" "b/docs/container/2.2.\346\236\232\344\270\276\345\256\271\345\231\250.html" index 27aa69d6..7454626f 100644 --- "a/docs/container/2.2.\346\236\232\344\270\276\345\256\271\345\231\250.html" +++ "b/docs/container/2.2.\346\236\232\344\270\276\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.3.\345\270\270\351\207\217\345\256\271\345\231\250.html" "b/docs/container/2.3.\345\270\270\351\207\217\345\256\271\345\231\250.html" index c4b2aa83..9be2876a 100644 --- "a/docs/container/2.3.\345\270\270\351\207\217\345\256\271\345\231\250.html" +++ "b/docs/container/2.3.\345\270\270\351\207\217\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.4.lambda\345\256\271\345\231\250.html" "b/docs/container/2.4.lambda\345\256\271\345\231\250.html" index 746b2db3..497d1f66 100644 --- "a/docs/container/2.4.lambda\345\256\271\345\231\250.html" +++ "b/docs/container/2.4.lambda\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.5.\346\226\271\346\263\225\345\256\271\345\231\250.html" "b/docs/container/2.5.\346\226\271\346\263\225\345\256\271\345\231\250.html" index d8ac1d65..7afb3494 100644 --- "a/docs/container/2.5.\346\226\271\346\263\225\345\256\271\345\231\250.html" +++ "b/docs/container/2.5.\346\226\271\346\263\225\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.6.\345\257\271\350\261\241\345\206\205\347\234\201.html" "b/docs/container/2.6.\345\257\271\350\261\241\345\206\205\347\234\201.html" index 570b3d51..f4fdbe17 100644 --- "a/docs/container/2.6.\345\257\271\350\261\241\345\206\205\347\234\201.html" +++ "b/docs/container/2.6.\345\257\271\350\261\241\345\206\205\347\234\201.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.7.\350\207\252\345\256\232\344\271\211\345\256\271\345\231\250.html" "b/docs/container/2.7.\350\207\252\345\256\232\344\271\211\345\256\271\345\231\250.html" index 64302edc..56fda836 100644 --- "a/docs/container/2.7.\350\207\252\345\256\232\344\271\211\345\256\271\345\231\250.html" +++ "b/docs/container/2.7.\350\207\252\345\256\232\344\271\211\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.8.\345\256\271\345\231\250\346\217\220\344\276\233\350\200\205.html" "b/docs/container/2.8.\345\256\271\345\231\250\346\217\220\344\276\233\350\200\205.html" index c311fdc6..9755ef3a 100644 --- "a/docs/container/2.8.\345\256\271\345\231\250\346\217\220\344\276\233\350\200\205.html" +++ "b/docs/container/2.8.\345\256\271\345\231\250\346\217\220\344\276\233\350\200\205.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/container/2.9.\345\257\271\350\261\241\345\256\271\345\231\250.html" "b/docs/container/2.9.\345\257\271\350\261\241\345\256\271\345\231\250.html" index 77adc220..373ede95 100644 --- "a/docs/container/2.9.\345\257\271\350\261\241\345\256\271\345\231\250.html" +++ "b/docs/container/2.9.\345\257\271\350\261\241\345\256\271\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/development/\351\205\215\347\275\256\350\247\243\346\236\220\345\231\250.html" "b/docs/development/\351\205\215\347\275\256\350\247\243\346\236\220\345\231\250.html" index 2260d36a..ce133630 100644 --- "a/docs/development/\351\205\215\347\275\256\350\247\243\346\236\220\345\231\250.html" +++ "b/docs/development/\351\205\215\347\275\256\350\247\243\346\236\220\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/execute/4.1.\346\211\213\345\212\250\345\241\253\345\205\205.html" "b/docs/execute/4.1.\346\211\213\345\212\250\345\241\253\345\205\205.html" index 2df68df7..0aef80e9 100644 --- "a/docs/execute/4.1.\346\211\213\345\212\250\345\241\253\345\205\205.html" +++ "b/docs/execute/4.1.\346\211\213\345\212\250\345\241\253\345\205\205.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/execute/4.2.\350\207\252\345\212\250\345\241\253\345\205\205.html" "b/docs/execute/4.2.\350\207\252\345\212\250\345\241\253\345\205\205.html" index 14145558..412dcff0 100644 --- "a/docs/execute/4.2.\350\207\252\345\212\250\345\241\253\345\205\205.html" +++ "b/docs/execute/4.2.\350\207\252\345\212\250\345\241\253\345\205\205.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/execute/4.3.\346\223\215\344\275\234\346\211\247\350\241\214\345\231\250.html" "b/docs/execute/4.3.\346\223\215\344\275\234\346\211\247\350\241\214\345\231\250.html" index d303286f..0d17e795 100644 --- "a/docs/execute/4.3.\346\223\215\344\275\234\346\211\247\350\241\214\345\231\250.html" +++ "b/docs/execute/4.3.\346\223\215\344\275\234\346\211\247\350\241\214\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/extension/6.1.MybatisPlus\346\211\251\345\261\225.html" "b/docs/extension/6.1.MybatisPlus\346\211\251\345\261\225.html" index 3bce8872..c6469289 100644 --- "a/docs/extension/6.1.MybatisPlus\346\211\251\345\261\225.html" +++ "b/docs/extension/6.1.MybatisPlus\346\211\251\345\261\225.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git a/docs/index.html b/docs/index.html index a0dc591d..1ac880c5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,8 +8,8 @@ - - + +

开箱即用

结合 springboot 自动装配,一行注解即可启用框架功能,避免繁琐的基本配置

上手简单

简单好懂的 API 和全面的注解配置支持,助你轻松上手

轻松扩展

结合 spring 依赖注入,轻松替换默认组件,丝滑接入自定义逻辑

适用于多种场景

支持分组或嵌套填充,也支持一对多或多对多批量填充,操作粒度最细可到每一个字段

丰富的数据源支持

默认即支持字典、枚举、常量类以及可执行方法等类型数据源,简单操作即可扩展更多数据源

强大的扩展功能

提供自动填充,多线程填充,缓存、动态表达式等扩展功能,还支持 mybatis-plus 等扩展插件

- + diff --git "a/docs/operation/3.0.\346\223\215\344\275\234\351\205\215\347\275\256.html" "b/docs/operation/3.0.\346\223\215\344\275\234\351\205\215\347\275\256.html" index 60873c4b..158976f4 100644 --- "a/docs/operation/3.0.\346\223\215\344\275\234\351\205\215\347\275\256.html" +++ "b/docs/operation/3.0.\346\223\215\344\275\234\351\205\215\347\275\256.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.1.\345\243\260\346\230\216\350\243\205\351\205\215\346\223\215\344\275\234.html" "b/docs/operation/3.1.\345\243\260\346\230\216\350\243\205\351\205\215\346\223\215\344\275\234.html" index 1b3a2560..bbe7cf30 100644 --- "a/docs/operation/3.1.\345\243\260\346\230\216\350\243\205\351\205\215\346\223\215\344\275\234.html" +++ "b/docs/operation/3.1.\345\243\260\346\230\216\350\243\205\351\205\215\346\223\215\344\275\234.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.2.\351\205\215\347\275\256\345\261\236\346\200\247\346\230\240\345\260\204.html" "b/docs/operation/3.2.\351\205\215\347\275\256\345\261\236\346\200\247\346\230\240\345\260\204.html" index 8a6f5e30..d1c75391 100644 --- "a/docs/operation/3.2.\351\205\215\347\275\256\345\261\236\346\200\247\346\230\240\345\260\204.html" +++ "b/docs/operation/3.2.\351\205\215\347\275\256\345\261\236\346\200\247\346\230\240\345\260\204.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.3.\346\214\207\345\256\232\350\243\205\351\205\215\345\244\204\347\220\206\345\231\250.html" "b/docs/operation/3.3.\346\214\207\345\256\232\350\243\205\351\205\215\345\244\204\347\220\206\345\231\250.html" index e8b8329b..952934bf 100644 --- "a/docs/operation/3.3.\346\214\207\345\256\232\350\243\205\351\205\215\345\244\204\347\220\206\345\231\250.html" +++ "b/docs/operation/3.3.\346\214\207\345\256\232\350\243\205\351\205\215\345\244\204\347\220\206\345\231\250.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.4.\346\213\206\345\215\270\345\265\214\345\245\227\345\257\271\350\261\241.html" "b/docs/operation/3.4.\346\213\206\345\215\270\345\265\214\345\245\227\345\257\271\350\261\241.html" index a572acf0..54b49fbe 100644 --- "a/docs/operation/3.4.\346\213\206\345\215\270\345\265\214\345\245\227\345\257\271\350\261\241.html" +++ "b/docs/operation/3.4.\346\213\206\345\215\270\345\265\214\345\245\227\345\257\271\350\261\241.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.5.\346\223\215\344\275\234\345\210\206\347\273\204.html" "b/docs/operation/3.5.\346\223\215\344\275\234\345\210\206\347\273\204.html" index 750e565d..b7908ebc 100644 --- "a/docs/operation/3.5.\346\223\215\344\275\234\345\210\206\347\273\204.html" +++ "b/docs/operation/3.5.\346\223\215\344\275\234\345\210\206\347\273\204.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.6.\346\223\215\344\275\234\346\216\222\345\272\217.html" "b/docs/operation/3.6.\346\223\215\344\275\234\346\216\222\345\272\217.html" index d7f934c5..a74bdf88 100644 --- "a/docs/operation/3.6.\346\223\215\344\275\234\346\216\222\345\272\217.html" +++ "b/docs/operation/3.6.\346\223\215\344\275\234\346\216\222\345\272\217.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/operation/3.7.\346\223\215\344\275\234\350\200\205\346\216\245\345\217\243.html" "b/docs/operation/3.7.\346\223\215\344\275\234\350\200\205\346\216\245\345\217\243.html" index d2cd1ecf..f58639c5 100644 --- "a/docs/operation/3.7.\346\223\215\344\275\234\350\200\205\346\216\245\345\217\243.html" +++ "b/docs/operation/3.7.\346\223\215\344\275\234\350\200\205\346\216\245\345\217\243.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/other/\346\217\220\351\227\256\347\232\204\346\231\272\346\205\247.html" "b/docs/other/\346\217\220\351\227\256\347\232\204\346\231\272\346\205\247.html" index 4c84ad86..e205a65a 100644 --- "a/docs/other/\346\217\220\351\227\256\347\232\204\346\231\272\346\205\247.html" +++ "b/docs/other/\346\217\220\351\227\256\347\232\204\346\231\272\346\205\247.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.html" "b/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.html" index a03f37c2..99ce8e7a 100644 --- "a/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.html" +++ "b/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/other/\346\272\220\347\240\201\350\256\276\350\256\241.html" "b/docs/other/\346\272\220\347\240\201\350\256\276\350\256\241.html" index 580c55d0..ed5c378c 100644 --- "a/docs/other/\346\272\220\347\240\201\350\256\276\350\256\241.html" +++ "b/docs/other/\346\272\220\347\240\201\350\256\276\350\256\241.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git "a/docs/other/\350\201\224\347\263\273\344\275\234\350\200\205.html" "b/docs/other/\350\201\224\347\263\273\344\275\234\350\200\205.html" index 2ff418b7..6cfc8f37 100644 --- "a/docs/other/\350\201\224\347\263\273\344\275\234\350\200\205.html" +++ "b/docs/other/\350\201\224\347\263\273\344\275\234\350\200\205.html" @@ -8,8 +8,8 @@ - - + +
- + diff --git a/pom.xml b/pom.xml index a5a10fae..e2842886 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ - 2.0.0-ALPHA + 2.0.0-BATE 1.8 maven-central diff --git "a/website/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.md" "b/website/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.md" index be7eb15c..c96f7ea5 100644 --- "a/website/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.md" +++ "b/website/docs/other/\346\233\264\346\226\260\346\227\245\345\277\227.md" @@ -146,7 +146,7 @@ ## 2.0.0-BATE (2023-07-30) -这是 `2.0.0` 的第二个预览版本,在上一版本的基础上修复了一些 bug,并添加了少量新功能。 +这是 `2.0.0` 的第二个预览版本,在上一版本的基础上修复了一些 bug,并添加了一些新功能。 具体内容参见:[Milestone](https://github.com/opengoofy/crane4j/milestone/4)。 @@ -164,3 +164,4 @@ **Feat** - [当在注解中不指定 key 属性时,允许将当前对象作为 key 值](https://github.com/opengoofy/crane4j/issues/100); +- [`ReflectivePropertyOperator` 在没有找到 setter 或者 getter 方法时,应当支持直接基于属性进行读写](https://github.com/opengoofy/crane4j/issues/105);