<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [toc] ## 典型的方法注入 大部分的應用場景,bean都是單例的.當一個單例的bean需要和另一個單例的bean組合在一起,或者一個非單例的bean和另一個非單例的bean組合在一起,典型的處理方式就是把bean設置成另一個bean的屬性. 但是,當兩個bean的生命周期不一致時就有問題了,假設單例bean A需要使用非單例的bean B,容器只創建A一次,也就是只有一次機會設置A的屬性,所以不可能每次使用A的時候提供新的實例B. 一種解決方案就是放棄部分控制反轉,可以使bean A實現接口`ApplicationContextAware`來關聯容器,然后在每次需要B的時候,通過容器調用`getBean("B")`獲取新的實例,如下: ~~~java // a class that uses a stateful Command-style class to perform some processing package fiona.apple; // Spring-API imports import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class CommandManager implements ApplicationContextAware { private ApplicationContext applicationContext; public Object process(Map commandState) { // grab a new instance of the appropriate Command Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } protected Command createCommand() { // notice the Spring API dependency! return this.applicationContext.getBean("command", Command.class); } public void setApplicationContext( ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } } ~~~ 前面的這種方式不可取的,因為業務代碼和spring框架耦合在一起,方法注入是spring的高級特性,下面的查找方法的注入方式更干凈一點 > 了解方法注入的更多機制參考[blog](https://spring.io/blog/2004/08/06/method-injection/) ## 查找方法的注入 查找方法的注入會覆蓋容器管理bean的方法,Spring Framework通過使用CGLIB庫中的字節碼動態生成覆蓋該方法的子類,從而實現了方法注入。 > * 為了動態子類可以正常工作,spring容器中的要被繼承的類不能是final的,同時要重寫的方法也不能是final的 > * 單元測試類有個`abstract`方法,需要你自行實現 > * 組件掃描也需要具體的類來提取 > * 查找方法的注入不能用于工廠方法,也不能用于配置類的@Bean注解的方法,因為容器不負責創建對象,不能創建運行時子類 > 對上面的示例改造 ~~~ java package fiona.apple; // no more Spring imports! public abstract class CommandManager { public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } // okay... but where is the implementation of this method? protected abstract Command createCommand(); } ~~~ 需要方法注入的`createCommand`,必須滿足下面的方法簽名 ~~~ <public|protected> [abstract] <return-type> theMethodName(no-arguments); ~~~ 如果是方法是`abstract`的,動態子類會實現它,否則動態子類會重寫原始類的方法,例如: ~~~xml <!-- a stateful bean deployed as a prototype (non-singleton) --> <bean id="myCommand" class="fiona.apple.AsyncCommand" scope="prototype"> <!-- inject dependencies here as required --> </bean> <!-- commandProcessor uses statefulCommandHelper --> <bean id="commandManager" class="fiona.apple.CommandManager"> <lookup-method name="createCommand" bean="myCommand"/> </bean> ~~~ `commandManager `需要新的myCommand實例時就調用自己的`createCommand`方法.如果實際需要,請仔細確認發布的bean `myCommand `為原型的,如果是發布為單例的,每次返回的都是同一個實例. 使用注解`@Lookup` 同樣可以實現 ~~~java public abstract class CommandManager { public Object process(Object commandState) { Command command = createCommand(); command.setState(commandState); return command.execute(); } @Lookup("myCommand") protected abstract Command createCommand(); } ~~~ 或者,更多的在返回類型上聲明目標,而不是在注解上 ~~~ public abstract class CommandManager { public Object process(Object commandState) { MyCommand command = createCommand(); command.setState(commandState); return command.execute(); } @Lookup protected abstract MyCommand createCommand(); } ~~~ > 另一種注入不同范圍的bean方式是`ObjectFactory/ Provider`,參考[Scoped beans as dependencies.](https://docs.spring.io/spring/docs/5.0.7.RELEASE/spring-framework-reference/core.html#beans-factory-scopes-other-injection) > 感興趣的同學會發現使用的類`ServiceLocatorFactoryBean`,在包`org.springframework.beans.factory.config` > ## 任意方法替換 比查找方法注入還少用的就是任意方法替換 基于xml的配置,使用`replaced-method`,考慮下面這種情況,想要重寫方法`computeValue` ~~~ public class MyValueCalculator { public String computeValue(String input) { // some real code... } // some other methods... } ~~~ 一個類實現接口`org.springframework.beans.factory.support.MethodReplacer`,提供一個新的方法 ~~~ /** * meant to be used to override the existing computeValue(String) * implementation in MyValueCalculator */ public class ReplacementComputeValue implements MethodReplacer { public Object reimplement(Object o, Method m, Object[] args) throws Throwable { // get the input value, work with it, and return a computed result String input = (String) args[0]; ... return ...; } } ~~~ 原始bean的定義和方法重寫如下: ~~~xml <bean id="myValueCalculator" class="x.y.z.MyValueCalculator"> <!-- arbitrary method replacement --> <replaced-method name="computeValue" replacer="replacementComputeValue"> <arg-type>String</arg-type> </replaced-method> </bean> <bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/> ~~~ 可以使用`<arg-type/>`表明重寫方法的參數,當方法有重載的時候,這個是必需的,為了方便使用,類型可以簡寫,如`java.lang.String` ~~~ java.lang.String String Str ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看