| 345 | | == 附錄 == |
| 346 | | === 資料集合 === |
| | 345 | |
| | 346 | |
| | 347 | = xml 與 properties = |
| | 348 | |
| | 349 | == 不用 bean.xml == |
| | 350 | |
| | 351 | 注意!此段原文可編譯但無法執行,以下編碼已經完全修正,請注意各檔案的路徑 |
| | 352 | |
| | 353 | 假設 AaBean 的內容如下: |
| | 354 | |
| | 355 | * src/waue/one/AaBean.java |
| | 356 | |
| | 357 | {{{ |
| | 358 | #!java |
| | 359 | package waue.one; |
| | 360 | |
| | 361 | public class AaBean { |
| | 362 | private String helloWord; |
| | 363 | |
| | 364 | public AaBean() { |
| | 365 | } |
| | 366 | |
| | 367 | public void setHelloWord(String helloWord) { |
| | 368 | this.helloWord = helloWord; |
| | 369 | } |
| | 370 | public String getHelloWord() { |
| | 371 | return helloWord; |
| | 372 | } |
| | 373 | } |
| | 374 | }}} |
| | 375 | |
| | 376 | === 只用 properties === |
| | 377 | |
| | 378 | XML檔案的階層格式適用於於組態設定,也因此許多的開源專案都將XML作為預設的組態定義方式,但通常也會提供非XML定義檔的方式,像屬性檔案. properties |
| | 379 | |
| | 380 | Spring也可以讓您使用屬性檔案定義Bean,例如定義一個 waue_one.properties: |
| | 381 | |
| | 382 | 注意! waue_one.properties 放在src 目錄底下,而非根目錄(非beans-config.xml 的目錄) |
| | 383 | |
| | 384 | 注意! aaBean.(class) 的()符號不可省略,否則運算時出錯 |
| | 385 | |
| | 386 | * src/waue_one.properties |
| | 387 | |
| | 388 | {{{ |
| | 389 | #!java |
| | 390 | aaBean.(class)=waue.one.AaBean |
| | 391 | aaBean.helloWord=Properties Welcome! |
| | 392 | }}} |
| | 393 | |
| | 394 | |
| | 395 | * src/waue/one/SpringDemo.java |
| | 396 | |
| | 397 | {{{ |
| | 398 | #!java |
| | 399 | package waue.one; |
| | 400 | |
| | 401 | import org.springframework.beans.factory.BeanFactory; |
| | 402 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| | 403 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
| | 404 | import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; |
| | 405 | import org.springframework.core.io.ClassPathResource; |
| | 406 | |
| | 407 | public class SpringDemo { |
| | 408 | public static void main(String[] args) { |
| | 409 | BeanDefinitionRegistry reg = |
| | 410 | new DefaultListableBeanFactory(); |
| | 411 | PropertiesBeanDefinitionReader reader = |
| | 412 | new PropertiesBeanDefinitionReader(reg); |
| | 413 | reader.loadBeanDefinitions( |
| | 414 | new ClassPathResource("waue_one.properties")); |
| | 415 | |
| | 416 | BeanFactory factory = (BeanFactory) reg; |
| | 417 | AaBean hello = (AaBean) factory.getBean("aaBean"); |
| | 418 | System.out.println(hello.getHelloWord()); |
| | 419 | } |
| | 420 | } |
| | 421 | }}} |
| | 422 | |
| | 423 | === main中直接綁值 === |
| | 424 | |
| | 425 | 不用 xml , 也不用 properties 來設定值,好處是,客戶端與定義檔是隔離的,他們無法接觸定義檔的內容,直接來看個例子: |
| | 426 | |
| | 427 | 注意!以下 SpringDemo.java 引用上面的 waue.one.AaBean.java , |
| | 428 | |
| | 429 | * src/waue/two/SpringDemo.java |
| | 430 | |
| | 431 | {{{ |
| | 432 | #!java |
| | 433 | |
| | 434 | package waue.two; |
| | 435 | |
| | 436 | import org.springframework.beans.MutablePropertyValues; |
| | 437 | import org.springframework.beans.factory.BeanFactory; |
| | 438 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| | 439 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
| | 440 | import org.springframework.beans.factory.support.RootBeanDefinition; |
| | 441 | |
| | 442 | import waue.one.AaBean; |
| | 443 | |
| | 444 | public class SpringDemo { |
| | 445 | public static void main(String[] args) { |
| | 446 | // 設置屬性 |
| | 447 | MutablePropertyValues properties = new MutablePropertyValues(); |
| | 448 | properties.addPropertyValue("helloWord", "Hello! Waue!"); |
| | 449 | |
| | 450 | // 設置Bean定義 |
| | 451 | RootBeanDefinition definition = new RootBeanDefinition(AaBean.class, |
| | 452 | properties); |
| | 453 | |
| | 454 | // 註冊Bean定義與Bean別名 |
| | 455 | BeanDefinitionRegistry reg = new DefaultListableBeanFactory(); |
| | 456 | reg.registerBeanDefinition("fooBean", definition); |
| | 457 | |
| | 458 | BeanFactory factory = (BeanFactory) reg; |
| | 459 | AaBean hello = (AaBean) factory.getBean("fooBean"); |
| | 460 | System.out.println(hello.getHelloWord()); |
| | 461 | } |
| | 462 | } |
| | 463 | }}} |
| | 464 | |
| | 465 | |
| | 466 | == properties / xml == |
| | 467 | |
| | 468 | 藉由這個類別,您可以在.properties中設定一些優先屬性設定,這個設定如果與XML中的屬性定義有相衝突,則以.properties中的設定為主 |
| | 469 | |
| | 470 | 注意! 此時 properties 檔必須跟 xml 檔放在一起 |
| | 471 | |
| | 472 | 注意! xml 內的value 值無意義,因為都已 properties 為主,而 properties 也不可以因為 xml 已經設定了該property 屬性,而不給 aaBean.helloWord |
| | 473 | |
| | 474 | |
| | 475 | * /waue_one.properties |
| | 476 | |
| | 477 | {{{ |
| | 478 | #!java |
| | 479 | aaBean.helloWord=Setup Properties with beans-config |
| | 480 | }}} |
| | 481 | |
| | 482 | * /beans-config.xml |
| | 483 | |
| | 484 | {{{ |
| | 485 | #!xml |
| | 486 | |
| | 487 | <?xml version="1.0" encoding="UTF-8"?> |
| | 488 | <beans xmlns="http://www.springframework.org/schema/beans" |
| | 489 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | 490 | xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> |
| | 491 | <bean id="configBean" |
| | 492 | class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> |
| | 493 | <property name="location"> |
| | 494 | <value>waue_one.properties</value> |
| | 495 | </property> |
| | 496 | </bean> |
| | 497 | |
| | 498 | <bean id="aaBean" class="waue.one.AaBean"> |
| | 499 | <property name="helloWord"> |
| | 500 | <value> </value> |
| | 501 | </property> |
| | 502 | </bean> |
| | 503 | |
| | 504 | </beans> |
| | 505 | }}} |
| | 506 | |
| | 507 | * src/waue/one/SpringDemo.java (同前) |
| | 508 | |
| | 509 | {{{ |
| | 510 | #!java |
| | 511 | package waue.one; |
| | 512 | |
| | 513 | import org.springframework.context.ApplicationContext; |
| | 514 | import org.springframework.context.support.FileSystemXmlApplicationContext; |
| | 515 | |
| | 516 | public class SpringDemo { |
| | 517 | public static void main(String[] args) throws InterruptedException { |
| | 518 | ApplicationContext context = |
| | 519 | new FileSystemXmlApplicationContext("beans-config.xml"); |
| | 520 | |
| | 521 | AaBean hello = |
| | 522 | (AaBean) context.getBean("aaBean"); |
| | 523 | System.out.println(hello.getHelloWord()); |
| | 524 | } |
| | 525 | } |
| | 526 | }}} |
| | 527 | |
| | 528 | * src/waue/one/AaBean.java (同前) |
| | 529 | |
| | 530 | {{{ |
| | 531 | #!java |
| | 532 | package waue.one; |
| | 533 | |
| | 534 | public class AaBean { |
| | 535 | private String helloWord; |
| | 536 | |
| | 537 | public AaBean() { |
| | 538 | } |
| | 539 | |
| | 540 | public void setHelloWord(String helloWord) { |
| | 541 | this.helloWord = helloWord; |
| | 542 | } |
| | 543 | public String getHelloWord() { |
| | 544 | return helloWord; |
| | 545 | } |
| | 546 | } |
| | 547 | }}} |
| | 548 | |
| | 549 | |
| | 550 | |
| | 551 | |
| | 552 | |
| | 553 | |
| | 554 | = 進階 bean 設定 = |
| | 555 | |
| | 556 | |
| | 557 | |
| | 558 | |
| | 559 | == bean 給值的前後設定 == |
| | 560 | |
| | 561 | 在Bean的屬性被Spring容器設定之後,您還有機會自訂一些對Bean的修正,您可以實作org.springframework.beans.factory.config.BeanPostProcessor介面: |
| | 562 | |
| | 563 | {{{ |
| | 564 | #!java |
| | 565 | package org.springframework.beans.factory.config; |
| | 566 | public interface BeanPostProcessor { |
| | 567 | public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException; |
| | 568 | public Object postProcessAfterInitialization(Object bean, String name) throws BeansException; |
| | 569 | } |
| | 570 | }}} |
| | 571 | |
| | 572 | postProcessBeforeInitialization()方法會在Bean初始化動作之前(例如InitializingBean的 afterPropertiesSet()方法或自定義的init方法)被呼叫,而postProcessAfterInitialization()方法會在Bean初始化之後立即被呼叫。 |
| | 573 | |
| | 574 | 舉個例子來說,您可以實作一個大寫修正器,對於String型態的Bean屬性,無論在定義檔中是設定為大寫或小寫,在Bean屬性設定之後,您可以在大寫修正器中將所有的String改為大寫,例如: |
| | 575 | |
| | 576 | * UpperCaseModifier.java |
| | 577 | |
| | 578 | {{{ |
| | 579 | #!java |
| | 580 | package onlyfun.caterpillar; |
| | 581 | |
| | 582 | import java.lang.reflect.Field; |
| | 583 | |
| | 584 | import org.springframework.beans.BeansException; |
| | 585 | import org.springframework.beans.factory.config.BeanPostProcessor; |
| | 586 | |
| | 587 | public class UpperCaseModifier implements BeanPostProcessor { |
| | 588 | |
| | 589 | public Object postProcessBeforeInitialization( |
| | 590 | Object bean, String name) throws BeansException { |
| | 591 | Field[] fields = bean.getClass().getDeclaredFields(); |
| | 592 | |
| | 593 | for(int i = 0; i < fields.length; i++) { |
| | 594 | if(fields[i].getType().equals(String.class)) { |
| | 595 | fields[i].setAccessible(true); |
| | 596 | try { |
| | 597 | String original = (String) fields[i].get(bean); |
| | 598 | fields[i].set(bean, original.toUpperCase()); |
| | 599 | } catch (IllegalArgumentException e) { |
| | 600 | e.printStackTrace(); |
| | 601 | } catch (IllegalAccessException e) { |
| | 602 | e.printStackTrace(); |
| | 603 | } |
| | 604 | } |
| | 605 | } |
| | 606 | |
| | 607 | return bean; |
| | 608 | } |
| | 609 | |
| | 610 | public Object postProcessAfterInitialization( |
| | 611 | Object bean, String name) throws BeansException { |
| | 612 | return bean; |
| | 613 | } |
| | 614 | |
| | 615 | } |
| | 616 | }}} |
| | 617 | |
| | 618 | 假設您定義了這麼一個Bean類別: |
| | 619 | |
| | 620 | * HelloBean.java |
| | 621 | |
| | 622 | {{{ |
| | 623 | #!java |
| | 624 | package onlyfun.caterpillar; |
| | 625 | |
| | 626 | public class HelloBean { |
| | 627 | private String helloWord; |
| | 628 | |
| | 629 | public HelloBean() { |
| | 630 | } |
| | 631 | |
| | 632 | public void setHelloWord(String helloWord) { |
| | 633 | this.helloWord = helloWord; |
| | 634 | } |
| | 635 | public String getHelloWord() { |
| | 636 | return helloWord; |
| | 637 | } |
| | 638 | } |
| | 639 | }}} |
| | 640 | |
| | 641 | ApplicationContext會自動偵測您是否在定義檔中定義了實作BeanPostProcessor介面的類別,例如: |
| | 642 | |
| | 643 | * beans-config.xml |
| | 644 | |
| | 645 | {{{ |
| | 646 | #!java |
| | 647 | <?xml version="1.0" encoding="UTF-8"?> |
| | 648 | <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" |
| | 649 | "http://www.springframework.org/dtd/spring-beans.dtd"> |
| | 650 | |
| | 651 | <beans> |
| | 652 | <bean id="upperCaseModifier" |
| | 653 | class="onlyfun.caterpillar.UpperCaseModifier"/> |
| | 654 | |
| | 655 | <bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> |
| | 656 | <property name="helloWord"> |
| | 657 | <value>Hello!</value> |
| | 658 | </property> |
| | 659 | </bean> |
| | 660 | </beans> |
| | 661 | }}} |
| | 662 | |
| | 663 | Spring容器會在每一個Bean被初始化之前之後分別呼叫upperCaseModifier的 postProcessBeforeInitialization()方法與postProcessAfterInitialization()方法,以對Bean進行指定的相關修正,可以實際來看看以下的測試程式: |
| | 664 | |
| | 665 | * SpringDemo.java |
| | 666 | |
| | 667 | {{{ |
| | 668 | #!java |
| | 669 | package onlyfun.caterpillar; |
| | 670 | |
| | 671 | import org.springframework.context.ApplicationContext; |
| | 672 | import org.springframework.context.support.FileSystemXmlApplicationContext; |
| | 673 | |
| | 674 | public class SpringDemo { |
| | 675 | public static void main(String[] args) { |
| | 676 | ApplicationContext context = |
| | 677 | new FileSystemXmlApplicationContext("beans-config.xml"); |
| | 678 | |
| | 679 | HelloBean hello = |
| | 680 | (HelloBean) context.getBean("helloBean"); |
| | 681 | System.out.println(hello.getHelloWord()); |
| | 682 | } |
| | 683 | } |
| | 684 | }}} |
| | 685 | |
| | 686 | 執行結果如下: |
| | 687 | {{{ |
| | 688 | HELLO! |
| | 689 | }}} |
| | 690 | 雖然您在定義檔中的helloBean之helloWord屬性是設定小寫字母,但upperCaseModifier將之改為大寫字母了。 |
| | 691 | |
| | 692 | == 資料集合 == |
| 435 | | = xml 與 properties = |
| 436 | | |
| 437 | | == 不用 bean.xml == |
| 438 | | |
| 439 | | 注意!此段原文可編譯但無法執行,以下編碼已經完全修正,請注意各檔案的路徑 |
| 440 | | |
| 441 | | 假設 AaBean 的內容如下: |
| 442 | | |
| 443 | | * src/waue/one/AaBean.java |
| 444 | | |
| 445 | | {{{ |
| 446 | | #!java |
| 447 | | package waue.one; |
| 448 | | |
| 449 | | public class AaBean { |
| 450 | | private String helloWord; |
| 451 | | |
| 452 | | public AaBean() { |
| 453 | | } |
| 454 | | |
| 455 | | public void setHelloWord(String helloWord) { |
| 456 | | this.helloWord = helloWord; |
| 457 | | } |
| 458 | | public String getHelloWord() { |
| 459 | | return helloWord; |
| 460 | | } |
| 461 | | } |
| 462 | | }}} |
| 463 | | |
| 464 | | === 只用 properties === |
| 465 | | |
| 466 | | XML檔案的階層格式適用於於組態設定,也因此許多的開源專案都將XML作為預設的組態定義方式,但通常也會提供非XML定義檔的方式,像屬性檔案. properties |
| 467 | | |
| 468 | | Spring也可以讓您使用屬性檔案定義Bean,例如定義一個 waue_one.properties: |
| 469 | | |
| 470 | | 注意! waue_one.properties 放在src 目錄底下,而非根目錄(非beans-config.xml 的目錄) |
| 471 | | |
| 472 | | 注意! aaBean.(class) 的()符號不可省略,否則運算時出錯 |
| 473 | | |
| 474 | | * src/waue_one.properties |
| 475 | | |
| 476 | | {{{ |
| 477 | | #!java |
| 478 | | aaBean.(class)=waue.one.AaBean |
| 479 | | aaBean.helloWord=Properties Welcome! |
| 480 | | }}} |
| 481 | | |
| 482 | | |
| 483 | | * src/waue/one/SpringDemo.java |
| 484 | | |
| 485 | | {{{ |
| 486 | | #!java |
| 487 | | package waue.one; |
| 488 | | |
| 489 | | import org.springframework.beans.factory.BeanFactory; |
| 490 | | import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| 491 | | import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
| 492 | | import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; |
| 493 | | import org.springframework.core.io.ClassPathResource; |
| 494 | | |
| 495 | | public class SpringDemo { |
| 496 | | public static void main(String[] args) { |
| 497 | | BeanDefinitionRegistry reg = |
| 498 | | new DefaultListableBeanFactory(); |
| 499 | | PropertiesBeanDefinitionReader reader = |
| 500 | | new PropertiesBeanDefinitionReader(reg); |
| 501 | | reader.loadBeanDefinitions( |
| 502 | | new ClassPathResource("waue_one.properties")); |
| 503 | | |
| 504 | | BeanFactory factory = (BeanFactory) reg; |
| 505 | | AaBean hello = (AaBean) factory.getBean("aaBean"); |
| 506 | | System.out.println(hello.getHelloWord()); |
| 507 | | } |
| 508 | | } |
| 509 | | }}} |
| 510 | | |
| 511 | | === main中直接綁值 === |
| 512 | | |
| 513 | | 不用 xml , 也不用 properties 來設定值,好處是,客戶端與定義檔是隔離的,他們無法接觸定義檔的內容,直接來看個例子: |
| 514 | | |
| 515 | | 注意!以下 SpringDemo.java 引用上面的 waue.one.AaBean.java , |
| 516 | | |
| 517 | | * src/waue/two/SpringDemo.java |
| 518 | | |
| 519 | | {{{ |
| 520 | | #!java |
| 521 | | |
| 522 | | package waue.two; |
| 523 | | |
| 524 | | import org.springframework.beans.MutablePropertyValues; |
| 525 | | import org.springframework.beans.factory.BeanFactory; |
| 526 | | import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| 527 | | import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
| 528 | | import org.springframework.beans.factory.support.RootBeanDefinition; |
| 529 | | |
| 530 | | import waue.one.AaBean; |
| 531 | | |
| 532 | | public class SpringDemo { |
| 533 | | public static void main(String[] args) { |
| 534 | | // 設置屬性 |
| 535 | | MutablePropertyValues properties = new MutablePropertyValues(); |
| 536 | | properties.addPropertyValue("helloWord", "Hello! Waue!"); |
| 537 | | |
| 538 | | // 設置Bean定義 |
| 539 | | RootBeanDefinition definition = new RootBeanDefinition(AaBean.class, |
| 540 | | properties); |
| 541 | | |
| 542 | | // 註冊Bean定義與Bean別名 |
| 543 | | BeanDefinitionRegistry reg = new DefaultListableBeanFactory(); |
| 544 | | reg.registerBeanDefinition("fooBean", definition); |
| 545 | | |
| 546 | | BeanFactory factory = (BeanFactory) reg; |
| 547 | | AaBean hello = (AaBean) factory.getBean("fooBean"); |
| 548 | | System.out.println(hello.getHelloWord()); |
| 549 | | } |
| 550 | | } |
| 551 | | }}} |
| 552 | | |
| 553 | | |
| 554 | | == properties / xml == |
| 555 | | |
| 556 | | 藉由這個類別,您可以在.properties中設定一些優先屬性設定,這個設定如果與XML中的屬性定義有相衝突,則以.properties中的設定為主 |
| 557 | | |
| 558 | | 注意! 此時 properties 檔必須跟 xml 檔放在一起 |
| 559 | | |
| 560 | | 注意! xml 內的value 值無意義,因為都已 properties 為主,而 properties 也不可以因為 xml 已經設定了該property 屬性,而不給 aaBean.helloWord |
| 561 | | |
| 562 | | |
| 563 | | * /waue_one.properties |
| 564 | | |
| 565 | | {{{ |
| 566 | | #!java |
| 567 | | aaBean.helloWord=Setup Properties with beans-config |
| 568 | | }}} |
| 569 | | |
| 570 | | * /beans-config.xml |
| 571 | | |
| 572 | | {{{ |
| 573 | | #!xml |
| 574 | | |
| 575 | | <?xml version="1.0" encoding="UTF-8"?> |
| 576 | | <beans xmlns="http://www.springframework.org/schema/beans" |
| 577 | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 578 | | xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> |
| 579 | | <bean id="configBean" |
| 580 | | class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> |
| 581 | | <property name="location"> |
| 582 | | <value>waue_one.properties</value> |
| 583 | | </property> |
| 584 | | </bean> |
| 585 | | |
| 586 | | <bean id="aaBean" class="waue.one.AaBean"> |
| 587 | | <property name="helloWord"> |
| 588 | | <value> </value> |
| 589 | | </property> |
| 590 | | </bean> |
| 591 | | |
| 592 | | </beans> |
| 593 | | }}} |
| 594 | | |
| 595 | | * src/waue/one/SpringDemo.java (同前) |
| 596 | | |
| 597 | | {{{ |
| 598 | | #!java |
| 599 | | package waue.one; |
| 600 | | |
| 601 | | import org.springframework.context.ApplicationContext; |
| 602 | | import org.springframework.context.support.FileSystemXmlApplicationContext; |
| 603 | | |
| 604 | | public class SpringDemo { |
| 605 | | public static void main(String[] args) throws InterruptedException { |
| 606 | | ApplicationContext context = |
| 607 | | new FileSystemXmlApplicationContext("beans-config.xml"); |
| 608 | | |
| 609 | | AaBean hello = |
| 610 | | (AaBean) context.getBean("aaBean"); |
| 611 | | System.out.println(hello.getHelloWord()); |
| 612 | | } |
| 613 | | } |
| 614 | | }}} |
| 615 | | |
| 616 | | * src/waue/one/AaBean.java (同前) |
| 617 | | |
| 618 | | {{{ |
| 619 | | #!java |
| 620 | | package waue.one; |
| 621 | | |
| 622 | | public class AaBean { |
| 623 | | private String helloWord; |
| 624 | | |
| 625 | | public AaBean() { |
| 626 | | } |
| 627 | | |
| 628 | | public void setHelloWord(String helloWord) { |
| 629 | | this.helloWord = helloWord; |
| 630 | | } |
| 631 | | public String getHelloWord() { |
| 632 | | return helloWord; |
| 633 | | } |
| 634 | | } |
| 635 | | }}} |
| 636 | | |
| 637 | | |
| 638 | | |
| 639 | | |
| 640 | | |
| 641 | | |
| 642 | | = 進階 bean 設定 = |
| 643 | | |
| 644 | | |
| 645 | | |
| 646 | | |
| 647 | | == bean 給值的前後設定 == |
| 648 | | |
| 649 | | 在Bean的屬性被Spring容器設定之後,您還有機會自訂一些對Bean的修正,您可以實作org.springframework.beans.factory.config.BeanPostProcessor介面: |
| 650 | | |
| 651 | | {{{ |
| 652 | | #!java |
| 653 | | package org.springframework.beans.factory.config; |
| 654 | | public interface BeanPostProcessor { |
| 655 | | public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException; |
| 656 | | public Object postProcessAfterInitialization(Object bean, String name) throws BeansException; |
| 657 | | } |
| 658 | | }}} |
| 659 | | |
| 660 | | postProcessBeforeInitialization()方法會在Bean初始化動作之前(例如InitializingBean的 afterPropertiesSet()方法或自定義的init方法)被呼叫,而postProcessAfterInitialization()方法會在Bean初始化之後立即被呼叫。 |
| 661 | | |
| 662 | | 舉個例子來說,您可以實作一個大寫修正器,對於String型態的Bean屬性,無論在定義檔中是設定為大寫或小寫,在Bean屬性設定之後,您可以在大寫修正器中將所有的String改為大寫,例如: |
| 663 | | |
| 664 | | * UpperCaseModifier.java |
| 665 | | |
| 666 | | {{{ |
| 667 | | #!java |
| 668 | | package onlyfun.caterpillar; |
| 669 | | |
| 670 | | import java.lang.reflect.Field; |
| 671 | | |
| 672 | | import org.springframework.beans.BeansException; |
| 673 | | import org.springframework.beans.factory.config.BeanPostProcessor; |
| 674 | | |
| 675 | | public class UpperCaseModifier implements BeanPostProcessor { |
| 676 | | |
| 677 | | public Object postProcessBeforeInitialization( |
| 678 | | Object bean, String name) throws BeansException { |
| 679 | | Field[] fields = bean.getClass().getDeclaredFields(); |
| 680 | | |
| 681 | | for(int i = 0; i < fields.length; i++) { |
| 682 | | if(fields[i].getType().equals(String.class)) { |
| 683 | | fields[i].setAccessible(true); |
| 684 | | try { |
| 685 | | String original = (String) fields[i].get(bean); |
| 686 | | fields[i].set(bean, original.toUpperCase()); |
| 687 | | } catch (IllegalArgumentException e) { |
| 688 | | e.printStackTrace(); |
| 689 | | } catch (IllegalAccessException e) { |
| 690 | | e.printStackTrace(); |
| 691 | | } |
| 692 | | } |
| 693 | | } |
| 694 | | |
| 695 | | return bean; |
| 696 | | } |
| 697 | | |
| 698 | | public Object postProcessAfterInitialization( |
| 699 | | Object bean, String name) throws BeansException { |
| 700 | | return bean; |
| 701 | | } |
| 702 | | |
| 703 | | } |
| 704 | | }}} |
| 705 | | |
| 706 | | 假設您定義了這麼一個Bean類別: |
| 707 | | |
| 708 | | * HelloBean.java |
| 709 | | |
| 710 | | {{{ |
| 711 | | #!java |
| 712 | | package onlyfun.caterpillar; |
| 713 | | |
| 714 | | public class HelloBean { |
| 715 | | private String helloWord; |
| 716 | | |
| 717 | | public HelloBean() { |
| 718 | | } |
| 719 | | |
| 720 | | public void setHelloWord(String helloWord) { |
| 721 | | this.helloWord = helloWord; |
| 722 | | } |
| 723 | | public String getHelloWord() { |
| 724 | | return helloWord; |
| 725 | | } |
| 726 | | } |
| 727 | | }}} |
| 728 | | |
| 729 | | ApplicationContext會自動偵測您是否在定義檔中定義了實作BeanPostProcessor介面的類別,例如: |
| 730 | | |
| 731 | | * beans-config.xml |
| 732 | | |
| 733 | | {{{ |
| 734 | | #!java |
| 735 | | <?xml version="1.0" encoding="UTF-8"?> |
| 736 | | <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" |
| 737 | | "http://www.springframework.org/dtd/spring-beans.dtd"> |
| 738 | | |
| 739 | | <beans> |
| 740 | | <bean id="upperCaseModifier" |
| 741 | | class="onlyfun.caterpillar.UpperCaseModifier"/> |
| 742 | | |
| 743 | | <bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> |
| 744 | | <property name="helloWord"> |
| 745 | | <value>Hello!</value> |
| 746 | | </property> |
| 747 | | </bean> |
| 748 | | </beans> |
| 749 | | }}} |
| 750 | | |
| 751 | | Spring容器會在每一個Bean被初始化之前之後分別呼叫upperCaseModifier的 postProcessBeforeInitialization()方法與postProcessAfterInitialization()方法,以對Bean進行指定的相關修正,可以實際來看看以下的測試程式: |
| 752 | | |
| 753 | | * SpringDemo.java |
| 754 | | |
| 755 | | {{{ |
| 756 | | #!java |
| 757 | | package onlyfun.caterpillar; |
| 758 | | |
| 759 | | import org.springframework.context.ApplicationContext; |
| 760 | | import org.springframework.context.support.FileSystemXmlApplicationContext; |
| 761 | | |
| 762 | | public class SpringDemo { |
| 763 | | public static void main(String[] args) { |
| 764 | | ApplicationContext context = |
| 765 | | new FileSystemXmlApplicationContext("beans-config.xml"); |
| 766 | | |
| 767 | | HelloBean hello = |
| 768 | | (HelloBean) context.getBean("helloBean"); |
| 769 | | System.out.println(hello.getHelloWord()); |
| 770 | | } |
| 771 | | } |
| 772 | | }}} |
| 773 | | |
| 774 | | 執行結果如下: |
| 775 | | {{{ |
| 776 | | HELLO! |
| 777 | | }}} |
| 778 | | 雖然您在定義檔中的helloBean之helloWord屬性是設定小寫字母,但upperCaseModifier將之改為大寫字母了。 |
| 779 | | |
| 780 | | |
| 781 | | |