<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 【第十二章】零配置 之 12.4 基于Java類定義Bean配置元數據 ——跟我學spring3 ## 12.4? 基于Java類定義Bean配置元數據 ### 12.4.1? 概述 基于Java類定義Bean配置元數據,其實就是通過Java類定義Spring配置元數據,且直接消除XML配置文件。 基于Java類定義Bean配置元數據中的@Configuration注解的類等價于XML配置文件,@Bean注解的方法等價于XML配置文件中的Bean定義。 基于Java類定義Bean配置元數據需要通過AnnotationConfigApplicationContext加載配置類及初始化容器,類似于XML配置文件需要使用ClassPathXmlApplicationContext加載配置文件及初始化容器。 基于Java類定義Bean配置元數據需要CGLIB的支持,因此要保證類路徑中包括CGLIB的jar包。 ### 12.4.2? Hello World 首先讓我們看一下基于Java類如何定義Bean配置元數據,具體步驟如下: 1、? 通過@Configuration注解需要作為配置的類,表示該類將定義Bean配置元數據; 2、? 通過@Bean注解相應的方法,該方法名默認就是Bean名,該方法返回值就是Bean對象; 3、? 通過AnnotationConfigApplicationContext或子類加載基于Java類的配置。 接下來讓我們先來學習一下如何通過Java類定義Bean配置元數據吧: 1、定義配置元數據的Java類如下所示: ``` package cn.javass.spring.chapter12.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ApplicationContextConfig { @Bean public String message() { return "hello"; } } ``` 2、定義測試類,測試一下Java配置類是否工作: ``` package cn.javass.spring.chapter12.configuration; //省略import public class ConfigurationTest { @Test public void testHelloworld () { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class); Assert.assertEquals("hello", ctx.getBean("message")); } } ``` 測試沒有報錯說明測試通過了,那AnnotationConfigApplicationContext是如何工作的呢,接下來讓我們分析一下: * 使用@Configuration注解配置類,該配置類定義了Bean配置元數據; * 使用@Bean注解配置類中的方法,該方法名就是Bean的名字,該方法返回值就是Bean對象。 * 使用new AnnotationConfigApplicationContext(ApplicationContextConfig.class)創建應用上下文,構造器參數為使用@Configuration注解的配置類,讀取配置類進行實例化相應的Bean。 知道如何使用了,接下來就詳細介紹每個部分吧。 ### 12.4.3? @Configuration 通過@Configuration注解的類將被作為配置類使用,表示在該類中將定義Bean配置元數據,且使用@Configuration注解的類本身也是一個Bean,使用方式如下所示: ``` import org.springframework.context.annotation.Configuration; @Configuration("ctxConfig") public class ApplicationContextConfig { //定義Bean配置元數據 } ``` 因為使用@Configuration注解的類本身也是一個Bean,因為@Configuration被@Component注解了,因此@Configuration注解可以指定value屬性值,如“ctxConfig”就是該Bean的名字,如使用“ctx.getBean("ctxConfig")”將返回該Bean。 使用@Configuration注解的類不能是final的,且應該有一個默認無參構造器。 ### 12.4.4? @Bean 通過@Bean注解配置類中的相應方法,則該方法名默認就是Bean名,該方法返回值就是Bean對象,并定義了Spring IoC容器如何實例化、自動裝配、初始化Bean邏輯,具體使用方法如下: ``` @Bean(name={}, autowire=Autowire.NO, initMethod="", destroyMethod="") ``` * **name:**指定Bean的名字,可有多個,第一個作為Id,其他作為別名; * **autowire:**自動裝配,默認no表示不自動裝配該Bean,另外還有Autowire.BY_NAME表示根據名字自動裝配,Autowire.BY_TYPE表示根據類型自動裝配; * **initMethod和destroyMethod:**指定Bean的初始化和銷毀方法。 示例如下所示(ApplicationContextConfig.java) ``` @Bean public String message() { return new String("hello"); } ``` 如上使用方式等價于如下基于XML配置方式 ``` <bean id="message" class="java.lang.String"> <constructor-arg index="0" value="hello"/> </bean> ``` 使用@Bean注解的方法不能是private、final或static的。 ### 12.4.5? 提供更多的配置元數據 詳見【12.3.6? 提供更多的配置元數據】中介紹的各種注解,這些注解同樣適用于@Bean注解的方法。 ### 12.4.6? 依賴注入 基于Java類配置方式的Bean依賴注入有如下兩種方式: * 直接依賴注入,類似于基于XML配置方式中的顯示依賴注入; * 使用注解實現Bean依賴注入:如@Autowired等等。 在本示例中我們將使用【第三章? DI】中的測試Bean。 **1、?直接依賴注入:**包括構造器注入和setter注入。 * **構造器注入:**通過在@Bean注解的實例化方法中使用有參構造器實例化相應的Bean即可,如下所示(ApplicationContextConfig.java): ``` @Bean public HelloApi helloImpl3() { //通過構造器注入,分別是引用注入(message())和常量注入(1) return new HelloImpl3(message(), 1); //測試Bean詳見【3.1.2 構造器注入】 } ``` * **setter注入**:通過在@Bean注解的實例化方法中使用無參構造器實例化后,通過相應的setter方法注入即可,如下所示(ApplicationContextConfig.java): ``` @Bean public HelloApi helloImpl4() { HelloImpl4 helloImpl4 = new HelloImpl4();//測試Bean詳見【3.1.3 setter注入】 //通過setter注入注入引用 helloImpl4.setMessage(message()); //通過setter注入注入常量 helloImpl4.setIndex(1); return helloImpl4; } ``` **2、使用注解實現Bean依賴注入**:詳見【12.2? 注解實Bean依賴注入】。 具體測試方法如下(ConfigurationTest.java): ``` @Test public void testDependencyInject() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class); ctx.getBean("helloImpl3", HelloApi.class).sayHello(); ctx.getBean("helloImpl4", HelloApi.class).sayHello(); } ``` ### 12.4.7? 方法注入 在基于XML配置方式中,Spring支持查找方法注入和替換方法注入,但在基于Java配置方式中只支持查找方法注入,一般用于在一個單例Bean中注入一個原型Bean的情況,具體詳見【3.3.5? 方法注入】,如下所示(ApplicationContextConfig.java): ``` @Bean @Scope("singleton") public HelloApi helloApi2() { HelloImpl5 helloImpl5 = new HelloImpl5() { @Override public Printer createPrototypePrinter() { //方法注入,注入原型Bean return prototypePrinter(); } @Override public Printer createSingletonPrinter() { //方法注入,注入單例Bean return singletonPrinter(); } }; //依賴注入,注入單例Bean helloImpl5.setPrinter(singletonPrinter()); return helloImpl5; } ``` ``` @Bean @Scope(value="prototype") public Printer prototypePrinter() { return new Printer(); } @Bean @Scope(value="singleton") public Printer singletonPrinter() { return new Printer(); } ``` 具體測試方法如下(ConfigurationTest.java): ``` @Test public void testLookupMethodInject() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class); System.out.println("=======prototype sayHello======"); HelloApi helloApi2 = ctx.getBean("helloApi2", HelloApi.class); helloApi2.sayHello(); helloApi2 = ctx.getBean("helloApi2", HelloApi.class); helloApi2.sayHello(); } ``` 如上測試等價于【3.3.5? 方法注入】中的查找方法注入。 ### 12.4.8? @Import 類似于基于XML配置中的&lt;import/&gt;,基于Java的配置方式提供了@Import來組合模塊化的配置類,使用方式如下所示: ``` package cn.javass.spring.chapter12.configuration; //省略import @Configuration("ctxConfig2") @Import({ApplicationContextConfig.class}) public class ApplicationContextConfig2 { @Bean(name = {"message2"}) public String message() { return "hello"; } } ``` 具體測試方法如下(ConfigurationTest.java): ``` @Test public void importTest() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig2.class); Assert.assertEquals("hello", ctx.getBean("message")); } ``` 使用非常簡單,在此就不多介紹了。 ### 12.4.9? 結合基于Java和基于XML方式的配置 基于Java方式的配置方式不是為了完全替代基于XML方式的配置,兩者可以結合使用,因此可以有兩種結合使用方式: * 在基于Java方式的配置類中引入基于XML方式的配置文件; * 在基于XML方式的配置文件中中引入基于Java方式的配置。 **一、在基于Java方式的配置類中引入基于XML方式的配置文件:**在@Configuration注解的配置類上通過@ImportResource注解引入基于XML方式的配置文件,示例如下所示: 1、定義基于XML方式的配置文件(chapter12/configuration/importResource.xml): ``` <bean id="message3" class="java.lang.String"> <constructor-arg index="0" value="test"></constructor-arg> </bean> ``` 2、修改基于Java方式的配置類ApplicationContextConfig,添加如下注解: ``` @Configuration("ctxConfig") //1、使用@Configuration注解配置類 @ImportResource("classpath:chapter12/configuration/importResource.xml") public class ApplicationContextConfig { …… } ``` 使用@ImportResource引入基于XML方式的配置文件,如果有多個請使用@ImportResource({"config1.xml", "config2.xml"})方式指定多個配置文件。 **二、在基于XML方式的配置文件中中引入基于Java方式的配置:**直接在XML配置文件中聲明使用@Configuration注解的配置類即可,示例如下所示: 1、定義基于Java方式的使用@Configuration注解的配置類在此我們使用ApplicationContextConfig.java。 2、定義基于XML方式的配置文件(chapter12/configuration/xml-config.xml): ``` <context:annotation-config/> <bean id="ctxConfig" class="cn.javass.spring.chapter12.configuration.ApplicationContextConfig"/> ``` * &lt;context:annotation-config/&gt;:用于開啟對注解驅動支持,詳見【12.2? 注解實現Bean依賴注入】; * &lt;bean id="ctxConfig" class="……"/&gt;:直接將使用@Configuration注解的配置類在配置文件中進行Bean定義即可。 3、測試代碼如下所示(ConfigurationTest.java):: ``` public void testXmlConfig() { String configLocations[] = {"chapter12/configuration/xml-config.xml"}; ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations); Assert.assertEquals("hello", ctx.getBean("message")); } ``` 測試成功,說明通過在基于XML方式的配置文件中能獲取到基于Java方式的配置文件中定義的Bean,如“message”Bean。 ### 12.4.10? 基于Java方式的容器實例化 基于Java方式的容器由AnnotationConfigApplicationContext表示,其實例化方式主要有以下幾種: **一、對于只有一個@Configuration注解的配置類**,可以使用如下方式初始化容器: ``` AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class); ``` **二、對于有多個@Configuration注解的配置類**,可以使用如下方式初始化容器: ``` AnnotationConfigApplicationContext ctx1 = new AnnotationConfigApplicationContext(ApplicationContextConfig.class, ApplicationContextConfig2.class); ``` 或者 ``` AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext(); ctx2.register(ApplicationContextConfig.class); ctx2.register(ApplicationContextConfig2.class); ``` **三、對于【12.3??注解實現Bean定義】中通過掃描類路徑中的特殊注解類來自動注冊Bean定義**,可以使用如下方式來實現: ``` public void testComponentScan() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("cn.javass.chapter12.confiuration"); ctx.refresh(); Assert.assertEquals("hello", ctx.getBean("message")); } ``` 以上配置方式等價于基于XML方式中的如下配置: ``` <context:component-scan base-package="cn.javass.chapter12.confiuration"/> ``` **四、在web環境中使用基于Java方式的配置**,通過修改通用配置實現,詳見**【10.1.2通用配置】**: 1、修改通用配置中的Web應用上下文實現,在此需要使用AnnotationConfigWebApplicationContext: ``` <context-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </context-param> ``` **2、指定加載配置類**,類似于指定加載文件位置,在基于Java方式中需要指定需要加載的配置類: ``` <context-param> <param-name>contextConfigLocation</param-name> <param-value> cn.javass.spring.chapter12.configuration.ApplicationContextConfig, cn.javass.spring.chapter12.configuration.ApplicationContextConfig2 </param-value> </context-param> ``` * **contextConfigLocation**:除了可以指定配置類,還可以指定“掃描的類路徑”,其加載步驟如下: 1、首先驗證指定的配置是否是類,如果是則通過注冊配置類來完成Bean定義加載,即如通過ctx.register(ApplicationContextConfig.class)加載定義; 2、如果指定的配置不是類,則通過掃描類路徑方式加載注解Bean定義,即將通過ctx.scan("cn.javass.chapter12.confiuration")加載Bean定義。 原創內容,轉載請注明私塾在線【[http://sishuok.com/forum/blogPost/list/0/2550.html](http://sishuok.com/forum/blogPost/list/0/2550.html#7325)】
                  <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>

                              哎呀哎呀视频在线观看