国产无码免费,人妻口爆,国产V在线,99中文精品7,国产成人无码AA精品一,制度丝袜诱惑av,久久99免费麻辣视频,蜜臀久久99精品久久久久久酒店
        訂閱
        糾錯
        加入自媒體

        Bean的定義與控制、純Java運行與@Bean

        2019-04-11 10:39
        EAWorld
        關注

        全局配置初始化與銷毀方法

        IoC容器還提供了全局配置初始化與銷毀方法的配置:

        package x.y;public class A {    public void init(){        // 初始化資源    }    public void destroy(){        // 銷毀資源    }}

        <beans default-init-method="init" default-destroy-method="destroy">     <bean id="a" class="x.y.A"/>     <!-- bean configuration --></beans>

        通過在<beans>標簽上使用default-init-method和default-destroy-method 屬性參數,可以為容器中所有的Bean統一指定初始化和銷毀的生命周期方法。

        如果在<beans>上設定2個默認的生命周期方法,同時在<bean>上也指定了init-method或destroy-method,回調方法會以<bean>上的配置為準。這樣就保證全局配置與單獨配置可以共存。

        使用初始化或銷毀2個生命周期方法注意的要點:

        初始化和銷毀都提供了3種手段:XML配置、注解、以及實現接口。系統的各個部分會交由不同的團隊開發,不遵循統一的規范,建議使用滿足JSR規范的注解——@PostConstruct、@PreDestroy。如果是統一的團隊,準訓一致的規范,建議使用<beans>的屬性統一名稱使用全局配置。

        如果Bean設計到代理模式時(例如使用了AOP),那么生命周期方法被調用時,有可能代理類還沒有被創建出來。因為生命周期方法是實體類完成對應工作之后就會被調用,而與代理類無關。

        3.0新增容器啟動方法

        在3.0之前的Spring核心框架中,我們啟動一個Spring容器必須使用一個XML文件。而到了3.X之后的版本Spring為創建容器新增了一個入口類——AnnotationConfigApplicationContext

        AnnotationConfigApplicationContext和過去的ClassPathXmlApplicationContext、FileSystemXmlApplicationContext等方法不同的是他不用再指定任何XML配置文件,而是可以通過指定類向容器添加Bean。我們通過幾個簡單的例子來說明他的使用。

        以下例子只用于說明問題,源碼請到 gitee 自行 clone(http://t.cn/E6Wvo51),本節的代碼在 chkui.springcore.example.javabase.simple 包中。

        直接添加Bean

        我們可以通過AnnotationConfigApplicationContext直接向容器添加指定的類作為Bean,先定義我們的class:

        package chkui.springcore.example.javabase.simple.pureBean;
        class LolBean {  public String toString() {    return "I AM LOL!";  }}
        class WowBean {  public String toString() {    return "I AM WOW!";  }}

        然后向容器添加這些Bean:

        package chkui.springcore.example.javabase.simple;
        public class WithoutAnnotation {  public static void main(String[] args) {    ApplicationContext ctx = new AnnotationConfigApplicationContext(WowBean.class, LolBean.class);    System.out.println(ctx.getBean(WowBean.class));    System.out.println(ctx.getBean(LolBean.class));  }}

        這樣就啟動了一個Spring的容器,并且容器中包含了WowBean和LolBean這兩個類的單例。

        替代<beans>標簽

        @Configuration在之前介紹Spring核心容器的文章中出現過一兩次,配合各種注解的使用@Configuration可以替代<beans>配置中的所有功能。基本上AnnotationConfigApplicationContext和@Configuration組合使用就可以實現Spring容器純Java啟動。請看下面的例子。

        我們在前面例子的基礎上增加幾個類:

        package chkui.springcore.example.javabase.simple.bean;
        public class DotaBean {  public String toString() {    return "I AM Dota!";  }}
        @Componentpublic class PseBean {
         @Override  public String toString() {    return "I AM PSE!";  }}

        注意DotaBean上是沒有@Component注解的。然后添加@Configuration配置:

        package chkui.springcore.example.javabase.simple.bean;
        @Configuration@ComponentScan("chkui.springcore.example.javabase.simple.bean")public class Config {  @Bean  public DotaBean dotaBean() {    return new DotaBean();  }}

        最后運行他們:

        package chkui.springcore.example.javabase.simple;
        public class WithScan {  public static void main(String[] args) {    ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class, WowBean.class, LolBean.class);    System.out.println(ctx.getBean(Config.class));    System.out.println(ctx.getBean(PseBean.class));    System.out.println(ctx.getBean(WowBean.class));    System.out.println(ctx.getBean(LolBean.class));    System.out.println(ctx.getBean(DotaBean.class));  }}

        @Component已經在《Stereotype組件與Bean掃描(http://t.cn/E6WhYYk)》這篇文章介紹過,@ComponentScan的作用等價于<context:component-scan/>標簽,屬性參數都是一一對應的,只不過前者是駝峰命名規則(camelCase)——@ComponentScan(basePackages="..."),后者是短橫線命名規則(kebab-case)——<context:component-scan base-package="..."/>。實際上使用Annotation來替換XML配置中的內容,大部分都使用這種轉換方式。

        @Configuration和@Bean標簽會在后續的內容中詳細介紹。@Bean主要用于方法標記,表明這個方法返回一個要添加到容器中的Bean。

        AnnotationConfigApplicationContext的其他使用方法

        除了以上常規的使用方法,AnnotationConfigApplicationContext還有其他方式向容器添加Bean。

        可以使用AnnotationConfigApplicationContext::register方法來添加配置和Bean:

        public static void main(String[] args) {    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();    //動態添加配置文件    ctx.register(Config1.class, Config2.class);    //動態添加Bean    ctx.register(Bean1.class);    //刷新    ctx.refresh();}

        注意最后的refresh方法,這個方法來源于ConfigurableApplicationContext接口,然后是在AbstractApplicationContext中實現的。他的過程相當于銷毀之前已經創建的資源,然后再重新創建了一個新的容器。這里的代碼會執行以下幾步:

        new AnnotationConfigApplicationContext():創建一個新的容器,容器中沒有自定義的Bean。

        AnnotationConfigApplicationContext::register:向容器添加BeanDefinition(http://t.cn/E6WzQ7W),但是這些BeanDefinition并沒有轉化為容器中的Bean。

        ConfigurableApplicationContext::refresh():納入新添加的BeanDefinition重建容器。

        還可以直接使用AnnotationConfigApplicationContext::scan方法掃描指定的路徑:

        public static void main(String[] args) {    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();    ctx.scan("com.acme");    ctx.refresh();}

        執行原理和上面介紹的一樣。

        需要注意的是:如果你的工程中需要使用AnnotationConfigApplicationContext::register、AnnotationConfigApplicationContext::scan等方法創建容器和其中Bean的依賴關系,所有的Bean都只能在register或scan中添加。如果你既在AnnotationConfigApplicationContext的構造方法中添加了Bean,又使用AnnotationConfigApplicationContext::refresh()方法會拋出一個重復執行refresh的異常。AnnotationConfigApplicationContext::refresh()方法全局也只能被調用一次。

        @Bean注解

        @Bean注解等價于配置文件中的<bean>標簽,對應的參數也是將短橫線命名切換為駝峰命名——<bean init-method="..."> => @Bean(initMethod="...")。@Bean注解只能使用在方法上,方法必須是在@Configuration標記的類或者其他Bean中,兩者存在的差異會在后續的文章中介紹。下面通過一個例子來說明Bean的使用。

        以下例子只用于說明問題,源碼請到 gitee 自行 clone(http://t.cn/E6Wvo51),本節的代碼在 chkui.springcore.example.javabase.beanAnnotation 包中。

        定義兩個要添加到容器中的Bean:

        package chkui.springcore.example.javabase.beanAnnotation.bean;
        class FinalFantasy {  @Override  public String toString() {    return "Final Fantasy 1~15";  }  public void init() {    System.out.println("Final Fantasy init!");  }    public void destroy() {    System.out.println("Final Fantasy destroy!");  }}
        class DragonQuest {  public String toString() {    return "Dragon Quest 1~11";  }    @PostConstruct  public void init() {    System.out.println("Dragon Quest init!");  }    @PreDestroy  public void destroy() {    System.out.println("Dragon Quest destroy!");  }}

        定義一個功能接口及其實現類:

        package chkui.springcore.example.javabase.beanAnnotation.bean;
        interface Support {  void setFinalFantasy(FinalFantasy ff);  FinalFantasy getFinalFantasy();}class SupportImpl implements Support {  private FinalFantasy ff;   public void setFinalFantasy(FinalFantasy ff) {    this.ff = ff;  }  public FinalFantasy getFinalFantasy() {    return ff;  }}

        然后頂一個@Configuration類:

        package chkui.springcore.example.javabase.beanAnnotation.bean;
        public class BeanAnnotationConfig {  @Bean  public Support support(FinalFantasy ff) {    Support support = new SupportImpl();    support.setFinalFantasy(ff);    return support;  }    @Bean(initMethod="init", destroyMethod="destroy")  @Description("Final Fantasy")  public FinalFantasy finalFantasy() {    return new FinalFantasy();  }    @Bean(name= {"dragon-quest", "DragonQuest"})  public DragonQuest dragonQuest() {    return new DragonQuest();  }}

        最后運行他們:

        public class BeanAnnotApp {
         public static void main(String[] args) {    ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanAnnotationConfig.class);    Support support = ctx.getBean(Support.class);    System.out.println(support.getFinalFantasy());    System.out.println(ctx.getBean(DragonQuest.class));  }

        在配置類BeanAnnotationConfig中,我們配置了3個Bean。這里的寫在方法上的@Bean注解和寫在配置文件中的<bean>注解一個效果:

        @Bean中的initMethod和destroyMethod對應<bean>標簽中的init-method和destroy-method屬性。

        @Bean中的name參數只有一個值時相當于id,有多個的時候相當于設置了多個別名

        Support support(FinalFantasy ff):我們可以直接在方法中暴露參數來引入其他Bean,這就類似于配置中ref的功能。

        如果不指定initMethod和destroyMethod,使用JSR-330的生命周期注解(@PostConstruct、@PreDestroy)同樣有效

        關于作者:陳葵,目前現任職某跨境安全支付公司技術總監,中山大學密碼學與信息安全專業碩士。對金融級安全支付,高可用性云應用,分布式事物、DevOps有多年的經驗。雖肩負團隊管理的任務,但對Coding依然保持極大的興趣,熟讀Spring、React、Tensorflow等各類開源項目的核心代碼。目前主導通過數據分析+AI提升風控模型能力的研究。

        關于EAWorld:微服務,DevOps,數據治理,移動架構原創技術分享。關注EAWorld

        <上一頁  1  2  
        聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權或其他問題,請聯系舉報。

        發表評論

        0條評論,0人參與

        請輸入評論內容...

        請輸入評論/評論長度6~500個字

        您提交的評論過于頻繁,請輸入驗證碼繼續

        暫無評論

        暫無評論

          掃碼關注公眾號
          OFweek人工智能網
          獲取更多精彩內容
          文章糾錯
          x
          *文字標題:
          *糾錯內容:
          聯系郵箱:
          *驗 證 碼:

          粵公網安備 44030502002758號

          主站蜘蛛池模板: 欧美18在线观看| 黄色国产视频| 鹰潭市| 信阳市| 亚欧精品视频| 亚洲AV成人无码久久精品黑人| 久治县| 汉寿县| 久久久久久亚洲AV成人无码激情| 久久久久久久| 夜夜撸日日干| 阆中市| 襄汾县| 人妻少妇久久| 亚洲欧美另类在线| 福利在线视频导航| 少妇无码| 婷婷综合色| 国产欧美一区二区精品性色超碰| 91在线观看| 日日操影院| 留坝县| 91九色TS另类国产人妖| 国产精品va| 隆回县| 91亚色| 日本精品一区二区| 免费看无码网站成人A片| 狠狠干性视频| jjzz亚洲| 97成人精品一区二区三区狼人| 日韩美女99精品| 另类天堂天堂av| 538av| 超碰51| 色伊人网| 亚洲天堂手机在线| 亚洲一区二区av| 中文久久久无码| 国产中文| 亚洲第1色电影。|