日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring核心——IOC处理器扩展

發布時間:2025/4/16 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring核心——IOC处理器扩展 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

非侵入式框架

Spring一直標注自己是一個非侵入式框架。非侵入式設計的概念并不新鮮,目標就是降低使用者和框架代碼的耦合,畢竟框架的開發者和使用者幾乎肯定不是同一個團隊。Spring最早的非侵入式實現就是他的一系列XML配置,理想狀態下Spring框架的所有的功能都應該是通過配置實現的。元編程在Java中的使用現給非侵入式的設計提供了更好的解決方案,在Java中通過注解(Annotation)即可標記某個類、方法、域的附加功能,而無需通過繼承的方式來擴展原始框架沒有的功能。下面通過3段代碼的例子來說明侵入式與非侵入式的區別。

文章中的代碼僅僅用于說明原理,已經刪除了一些無關代碼,無法執行??蓤绦写a在:https://github.com/chkui/spring-core-example,如有需要請自行clone,僅支持gradle依賴。

一個基本的容器

下面的代碼是大致模仿的IoC容器創建Bean的過程。BeanFactory::createBeans方法傳入Bean的類型列表,而迭代器遍歷列表完成每一個類的實例創建:

/**框架代碼*/ package chkui.springcore.example.xml.beanpostprocessor.nopluging;//創建Bean的工廠類,由框架開發者開發 class BeanFactory {//創建一系列的Beanpublic List<Object> createBeans(List<Class<?>> clslist){return clslist.stream().map(cls->{return createBean(cls);}).collect(Collectors.toList());}//創建一個BeanObject createBean(Class<?> cls){//添加到容器return new BeanWrapper(cls.newInstance());} }//包裝代理 class BeanWrapper {private Object bean;public BeanWrapper(Object bean) {this.bean = bean;}@Overridepublic String toString() {return "Wrapper(" + this.bean.toString() + ")";} }

下面的代碼是框架使用者的代碼——將Bean1和Bean2交給BeanFactory來完成初始化:

/**使用端代碼*/ package chkui.springcore.example.xml.beanpostprocessor.nopluging;//import ...public class IocExtensionSampleNoPluging {public static void main(String[] args) {List<Class<?>> classes = Arrays.asList(new Class<?>[]{MyBean1.class, MyBean2.class});List<Object> ins = new BeanFactory().createBeans(classes);System.out.println("Result:" + ins.toString());} }//Bean1,由使用者編碼 class MyBean1 {public String toString() {return "MyBean1 Ins";} }//Bean2,使用者編碼 class MyBean2 {public String toString() {return "MyBean2 Ins";} }

classpath:chkui.springcore.example.xml.beanpostprocessor.nopluging.IocExtensionSample。源碼地址。

某個時刻,框架的使用者有個新需求是在要在每個Bean創建的前后進行一些處理。我們可以通過繼承的方式來實現功能。下面我們修改使用端代碼實現這個功能。

繼承實現功能擴展

通過繼承類BeanFactory,并修改createBean方法可以實現我們的需求:

package chkui.springcore.example.xml.beanpostprocessor.extend;//執行 public class IocExtensionSampleNoPluging {public static void main(String[] args) {List<Class<?>> classes = Arrays.asList(new Class<?>[]{MyBean1.class, MyBean2.class});List<Object> ins = new ModifyBeanFactory().createBeans(classes);System.out.println("Result:" + ins.toString());} }//新建一個BeanFactory的派生類,并修改createBean的實現,添加使用者的處理邏輯 class ModifyBeanFactory extends BeanFactory {Object createBean(Class<?> cls){Object ins = cls.newInstance();//添加容器之前的處理BeanWrapper wrapper = new BeanWrapper(ins);//添加容器之后的處理return wrapper;} }

classpath:chkui.springcore.example.xml.beanpostprocessor.extend.IocExtensionSample。源碼地址。

這里在使用者的代碼里新增了一個ModifyBeanFactory類,并重寫了createBean方法。在重寫的方法中實現我們需要的功能邏輯。但是這樣開發會出現以下2點問題:

  • 導致使用者的代碼與框架代碼產生了極強的耦合性。如果某天框架進行了調整,例如將方法名改為buildBean、或者增加了更多的代理模式會出現一些意想不到的問題。更麻煩的是可能會遇到一些到運行期才出現的問題。
  • 我們需要先理解框架的源碼才能植入我們的功能,這和很多設計模式的原則是背道而馳的。也會大大影響我們的開發效率。
  • 出現這些問題就叫做“侵入式”——框架代碼侵入到使用者的工程代碼,導致2者嚴重耦合,對未來的升級、擴展、二次開發都有深遠的影響。

    通過注解(Annotation)擴展功能

    實際上注解和在XML進行配置都是一樣的思路,只是注解講關系寫在了源碼上,而使用XML是將關系通過XML來描述。這里實現的功能就類似于在?Bean的定義與控制?一文中介紹的Bean的生命周期方法。

    使用注解最大的價值就是非侵入式。非侵入式的好處顯而易見:

  • 無需和框架代碼耦合,更新升級框架風險和成本都很小。
  • 任何時候我們需要需要更換框架,只需修改配置或注解,而無需再去調整我們自己的功能代碼。
  • 非侵入式也有一個問題,那就是接入的功能還是需要框架預設,而不可能像繼承那樣隨心所欲。

    我們將前面的代碼進行一些修改,支持通過注解來指定擴展的功能:

    package chkui.springcore.example.xml.beanpostprocessor.annotation;class BeanFactory {public List<Object> createBeans(List<Class<?>> clslist){//同前文...}Object createBean(Class<?> cls){BeanWrapper wrapper = null;Object ins = cls.newInstance();/**這里增加了一個Handle對象。Handle會對注解進行處理,確定添加容器前后的執行方法。*/Handle handle = processBeforeAndAfterHandle(ins);handle.exeBefore();wrapper = new BeanWrapper(ins);handle.exeAfter();return wrapper;}// 通過反射來確定Bean被添加到容器前后的執行方法。private Handle processBeforeAndAfterHandle(Object obj) {Method[] methods = obj.getClass().getDeclaredMethods();Handle handle = new Handle(obj);for(Method method : methods) {Annotation bef = method.getAnnotation(before.class);Annotation aft = method.getAnnotation(after.class);if(null != bef) handle.setBefore(method);if(null != aft) handle.setBefore(method);}return handle;} }

    下面是Handle處理器和對應的注解的代碼:

    class Handle{Object instance;Method before;Method after;Handle(Object ins){this.instance = ins;}void setBefore(Method method) {this.before = method;}void setAfter(Method method) {this.after = method;}void exeBefore(){if(null != this.before) {this.before.invoke(this.instance, null);}}void exeAfter(){if(null != this.after) {this.after.invoke(this.instance, null);}} }//注解---------------------------------------- @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface before {}@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface after{}

    使用者的代碼,我們將注解添加到Bean的對應的方法上:

    public class IocExtensionSampleNoPluging {public static void main(String[] args) {List<Class<?>> classes = Arrays.asList(new Class<?>[]{MyBean1.class, MyBean2.class});List<Object> ins = new BeanFactory().createBeans(classes);System.out.println("Result:" + ins.toString());} }//預設的Bean1 class MyBean1 {public String toString() {return "MyBean1 Ins";}@beforepublic void init() {System.out.println("Before Init:" + this.toString());} }//預設的Bean2 class MyBean2 {public String toString() {return "MyBean2 Ins";}@afterpublic void post() {System.out.println("After Init:" + this.toString());} }

    我們為MyBean1和MyBean2分別添加了init、post方法和對應的@before、@after注解。執行之后輸出一下內容:

    Before Init:MyBean1 Ins After Init:MyBean2 Ins Result:[Wrapper(MyBean1 Ins), Wrapper(MyBean2 Ins)]

    classpath:chkui.springcore.example.xml.beanpostprocessor.annotation.IocExtensionSample。源碼地址。

    注解對應的方法都順利執行。

    通過注解,我們實現了擴展功能,任何時候只需要通過添加或修改注解即可向容器擴展功能。在Spring核心功能里,Bean的生命周期管理都是通過這種思路實現的,除了注解之外還有XML支持。

    在使用spring的過程中,我想各位碼友多多少少都通過繼承Spring某些類來實現了一些需要擴展的功能。而且我發現網上很多使用spring某些功能的例子也是通過繼承實現的。建議盡量不要去采用這種加深耦合的方式實現擴展,Spring提供了多種多樣的容器擴展機制,后面的文章會一一介紹。

    后置處理器

    后置處理器——BeanPostProcessor是Spring核心框架容器擴展功能之一,作用和Bean的生命周期方法類似,也是在Bean完成初始化前后被調用。但是和生命周期方法不同的是,他無需在每一個Bean上去實現代碼,而是通過一個獨立的Bean來處理全局的初始化過程。

    BeanPostProcessor與Bean生命周期方法體現出的差異是:我們無論任何時候都可以加入處理器來實現擴展功能,這樣做的好處是無需調整之前的Bean的任何代碼也可以植入功能。

    這種實現方式與切面(AOP)有一些相似的地方,但是實現的方式是完全不一樣的,而且處理器會對所有Bean進行處理。

    BeanPostProcessor的實現非常簡單,只添加一個Bean實現BeanPostProcessor接口即可:

    package chkui.springcore.example.xml.beanpostprocessor; import org.springframework.beans.factory.config.BeanPostProcessor;public class Processor implements BeanPostProcessor {//初始化之前public Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}//初始化之后public Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("Bean '" + beanName + "' created : " + bean.toString());return bean;} }

    BeanPostProcessor的使用案例請查看實例代碼中?chkui.springcore.example.xml.beanpostprocessor 包中的代碼,包含:

    一個實體類:chkui.springcore.example.xml.entity.User

    一個服務接口和服務類:chkui.springcore.example.xml.service.UserService

    處理器:chkui.springcore.example.xml.beanpostprocessor.Processor

    Main入口:chkui.springcore.example.xml.beanpostprocessor.BeanPostProcessor

    配置文件:/src/main/resources/xml/config.xml

    更多的后置處理器說明

    見:https://www.chkui.com/article/spring/spring_core_post_processor_of_official

    ?

    轉載于:https://my.oschina.net/chkui/blog/1840824

    總結

    以上是生活随笔為你收集整理的Spring核心——IOC处理器扩展的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久国产香蕉 | 欧美视频第二页 | 午夜肉伦伦 | 蜜桃av久久久亚洲精品 | 日本成人免费在线 | 日韩av网址大全 | 黄页网址大全免费观看 | 女人被男人躁得好爽免费视频 | 亚洲欧美一区二区精品久久久 | 国产精品久久久影院 | 五月天婷婷社区 | 日本精品国产 | 午夜美女在线 | 亚洲男人天堂av | 国产黄片一区二区三区 | 亚洲乱强伦 | 操碰视频在线 | 尤物一区| 国产精品嫩草69影院 | 熟女俱乐部一区二区视频在线 | 中日韩男男gay无套 人人草人人干 | 欧美国产中文 | 国产精品国产三级国产Av车上的 | 日本成人激情 | 一级中文字幕 | 日本网站黄色 | 视频二区欧美 | 日韩专区一区 | 久久99网站 | 国内偷拍第一页 | 日本免费一区视频 | 九九九免费视频 | 在线日韩精品视频 | 亚洲av区无码字幕中文色 | 免费看大片a | 国产毛片一区 | 久久天天操| 日韩中文字幕精品视频 | 欧美乱妇日本无乱码特黄大片 | 亚洲无码精品一区二区三区 | 国产精品swag | 亚洲一区观看 | 黄色一极视频 | 理论片在线观看理伦片 | 欧美午夜精品一区二区三区 | 一级中文字幕 | 操一操日一日 | 国产精品久久成人 | 亚洲国产黄色 | 欧美激情综合网 | 日本欧美精品 | 日韩 在线 | 色涩视频在线观看 | 国产成人精品亚洲日本在线观看 | 曰曰操| 欧美性白人极品1819hd | 天天干夜夜想 | 黄色午夜 | 日韩在线观看视频一区二区 | 成人久久18免费网站图片 | 亚洲天堂一级 | www.青青草.com| 精品在线观看视频 | 国内av网站 | 日本在线www | 一级全黄色片 | 69社| 91成人福利 | juliaann第一次和老师 | 精品黑人一区二区三区在线观看 | 91中文字幕在线播放 | 国产一区二区三区18 | 草久久久| 91制服诱惑| 成人福利在线播放 | 美美女高清毛片视频免费观看 | 超碰久草 | 超碰碰碰碰 | 亚洲欧美日韩动漫 | 中文字幕丰满人伦在线 | 亚洲人成小说 | 韩国明星乱淫(高h)小说 | wwwjavhd| 亚洲午夜免费视频 | 日本三级黄色录像 | 国产r级在线 | 综合激情久久 | 亚洲一区图片 | 成人在线观看免费视频 | 艳妇乳肉豪妇荡乳av | 华丽的外出在线观看 | 日韩在线www| 在线观看av国产一区二区 | 日韩色黄大片 | 亚洲一区二区三区在线视频观看 | 午夜色播 | 山外人精品影院 | 黄色动漫在线观看 | 日韩va亚洲va欧美va久久 |