熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Spring攻略:創建Bean後處理器

2013-11-23 20:03:02  來源: Java開源技術 

  知識點

  Bean後處理器允許在初始化回調方法前後進行額外的Bean處理Bean後處理器的主要特性是逐個處理IoC容器中的所有Bean實例而不只是單個Bean實例一般來說Bean後處理器用於檢查Bean屬性的有效性或根據特定條件修改Bean屬性

  Bean後處理器的基本要求是實現BeanPostProcessor接口通過實現postProcessBeforeInitialization() 和 postProcessAfterInitialization() 方法可以在初始化回調方法前後處理所有BeanSpring將在調用初始化回調方法前後向這兩個方法傳遞每個Bean實例步驟如下

  ()構造函數或者工廠方法創建Bean實例

  ()為Bean屬性設值和Bean引用

  ()調用感知接口中定義的設值方法

  ()將Bean實例傳遞給每個Bean後處理器中的postProcessBeforeInitialization()方法

  ()調用初始化回調方法

  ()將Bean實例傳遞給每個Bean後處理器中的postProcessAfterInitialization()方法

  ()Bean准備就緒可以使用

  ()容器關閉時調用銷毀回調函數

  使用Bean工廠作為IoC容器時Bean後處理器只能編程注冊即通過addBeanPostProcessor方法注冊如果使用應用程序上下文只需要在Bean配置文件中聲明一個處理器實例它就會自動注冊

  代碼示例

  StorageConfig標記接口

  [java]

  package deprojectjackiespringrecipesnotespringadvancedioc;

  /**

  * 標記接口讓Bean後處理器區分應檢查的Bean

  * @author jackie

  *

  */

  public interface StorageConfig {

  public String getPath();

  }

  package deprojectjackiespringrecipesnotespringadvancedioc;

  /**

  * 標記接口讓Bean後處理器區分應檢查的Bean

  * @author jackie

  *

  */

  public interface StorageConfig {

  public String getPath();

  } Cashier類

  [java]

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioBufferedWriter;

  import javaioFile;

  import javaioFileWriter;

  import javaioIOException;

  import javautilDate;

  import orgspringframeworkbeansfactoryBeanNameAware;

  /**

  * Cashier類實現BeanNameAware感知接口和StorageConfig標記接口

  * @author jackie

  *

  */

  public class Cashier implements BeanNameAware StorageConfig {

  private String name;

  private BufferedWriter writer;

  private String path;

  public void setPath(String path) {

  thispath = path;

  }

  public void openFile() throws IOException {

  File file = new File(path name + txt);

  FileWriter fw = new FileWriter(file true);

  writer = new BufferedWriter(fw);

  }

  public void checkout(ShoppingCart cart) throws IOException {

  double total = ;

  for (Product product : cartgetItems()) {

  total += productgetPrice();

  }

  writerwrite(new Date() + \t + total + \r\n);

  writerflush();

  }

  public void closeFile() throws IOException {

  writerclose();

  }

  @Override

  public String getPath() {

  return path;

  }

  @Override

  public void setBeanName(String beanName) {

  thisname = beanName;

  }

  }

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioBufferedWriter;

  import javaioFile;

  import javaioFileWriter;

  import javaioIOException;

  import javautilDate;

  import orgspringframeworkbeansfactoryBeanNameAware;

  /**

  * Cashier類實現BeanNameAware感知接口和StorageConfig標記接口

  * @author jackie

  *

  */

  public class Cashier implements BeanNameAware StorageConfig {

  private String name;

  private BufferedWriter writer;

  private String path;

  public void setPath(String path) {

  thispath = path;

  }

  public void openFile() throws IOException {

  File file = new File(path name + txt);

  FileWriter fw = new FileWriter(file true);

  writer = new BufferedWriter(fw);

  }

  public void checkout(ShoppingCart cart) throws IOException {

  double total = ;

  for (Product product : cartgetItems()) {

  total += productgetPrice();

  }

  writerwrite(new Date() + \t + total + \r\n);

  writerflush();

  }

  public void closeFile() throws IOException {

  writerclose();

  }

  @Override

  public String getPath() {

  return path;

  }

  @Override

  public void setBeanName(String beanName) {

  thisname = beanName;

  }

  }

  PathCheckingBeanPostProcessor自定義Bean後處理器

  [java]

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioFile;

  import orgspringframeworkbeansBeansException;

  import orgspringframewonfigBeanPostProcessor;

  /**

  * 通用的組件確保文件在打開之前存在

  * @author jackie

  *

  */

  public class PathCheckingBeanPostProcessor implements BeanPostProcessor {

  /**

  * 在文件打開之前進行路徑檢查

  * 須返回所處理的Bean的一個實例

  */

  @Override

  public Object postProcessBeforeInitialization(Object bean String beanName)

  throws BeansException {

  // 如果Bean實現了StorageConfig接口檢查路徑是否存在

  if (bean instanceof StorageConfig) {

  String path = ((StorageConfig)bean)getPath();

  File file = new File(path);

  if (!fileexists()) {

  filemkdirs();

  }

  }

  return bean;

  }

  /**

  * 即使什麼都不做也必須返回原來的Bean實例

  */

  @Override

  public Object postProcessAfterInitialization(Object bean String beanName)

  throws BeansException {

  return bean;

  }

  }

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioFile;

  import orgspringframeworkbeansBeansException;

  import orgspringframewonfigBeanPostProcessor;

  /**

  * 通用的組件確保文件在打開之前存在

  * @author jackie

  *

  */

  public class PathCheckingBeanPostProcessor implements BeanPostProcessor {

  /**

  * 在文件打開之前進行路徑檢查

  * 須返回所處理的Bean的一個實例

  */

  @Override

  public Object postProcessBeforeInitialization(Object bean String beanName)

  throws BeansException {

  // 如果Bean實現了StorageConfig接口檢查路徑是否存在

  if (bean instanceof StorageConfig) {

  String path = ((StorageConfig)bean)getPath();

  File file = new File(path);

  if (!fileexists()) {

  filemkdirs();

  }

  }

  return bean;

  }

  /**

  * 即使什麼都不做也必須返回原來的Bean實例

  */

  @Override

  public Object postProcessAfterInitialization(Object bean String beanName)

  throws BeansException {

  return bean;

  }

  }Bean配置

  [html]

  <?xml version= encoding=UTF?>

  <beans xmlns=

  xmlns:xsi=instance

  xsi:schemaLocation= beansxsd>

  <! 注冊Bean後處理器 >

  <bean class=deprojectjackiespringrecipesnotespringadvancediocPathCheckingBeanPostProcessor />

  <bean id=aaa class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=AAA />

  <property name=price value= />

  </bean>

  <bean id=cdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=CDRW />

  <property name=price value= />

  </bean>

  <bean id=dvdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=DVDRW />

  <property name=price value= />

  </bean>

  <bean id=shoppingCart class=deprojectjackiespringrecipesnotespringadvancediocShoppingCart scope=prototype />

  <bean id=cashier class=deprojectjackiespringrecipesnotespringadvancediocCashier initmethod=openFile destroymethod=closeFile >

  <property name=path value=c:/cashier />

  </bean>

  </beans>

  <?xml version= encoding=UTF?>

  <beans xmlns=

  xmlns:xsi=instance

  xsi:schemaLocation= beansxsd>

  <! 注冊Bean後處理器 >

  <bean class=deprojectjackiespringrecipesnotespringadvancediocPathCheckingBeanPostProcessor />

  <bean id=aaa class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=AAA />

  <property name=price value= />

  </bean>

  <bean id=cdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=CDRW />

  <property name=price value= />

  </bean>

  <bean id=dvdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

  <property name=name value=DVDRW />

  <property name=price value= />

  </bean>

  <bean id=shoppingCart class=deprojectjackiespringrecipesnotespringadvancediocShoppingCart scope=prototype />

  <bean id=cashier class=deprojectjackiespringrecipesnotespringadvancediocCashier initmethod=openFile destroymethod=closeFile >

  <property name=path value=c:/cashier />

  </bean>

  </beans>測試類

  [java]

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioIOException;

  import orgjunitTest;

  import orgntextApplicationContext;

  import orgntextsupportClassPathXmlApplicationContext;

  /**

  * @author jackie

  *

  */

  public class BeanPostProcessorTest {

  @Test

  public void testBeanPostProcessor() throws IOException {

  ApplicationContext applicationContext = new ClassPathXmlApplicationContext(applicationContextxml);

  Product aaa = (Product) applicationContextgetBean(aaa);

  Product cdrw = (Product) applicationContextgetBean(cdrw);

  Product dvdrw = (Product) applicationContextgetBean(dvdrw);

  ShoppingCart shoppingCart = (ShoppingCart) applicationContextgetBean(shoppingCart);

  shoppingCartaddItem(aaa);

  shoppingCartaddItem(cdrw);

  shoppingCartaddItem(dvdrw);

  Cashier cashier = (Cashier) applicationContextgetBean(cashier);

  cashiercheckout(shoppingCart);

  }

  }

  package deprojectjackiespringrecipesnotespringadvancedioc;

  import javaioIOException;

  import orgjunitTest;

  import orgntextApplicationContext;

  import orgntextsupportClassPathXmlApplicationContext;

  /**

  * @author jackie

  *

  */

  public class BeanPostProcessorTest {

  @Test

  public void testBeanPostProcessor() throws IOException {

  ApplicationContext applicationContext = new ClassPathXmlApplicationContext(applicationContextxml);

  Product aaa = (Product) applicationContextgetBean(aaa);

  Product cdrw = (Product) applicationContextgetBean(cdrw);

  Product dvdrw = (Product) applicationContextgetBean(dvdrw);

  ShoppingCart shoppingCart = (ShoppingCart) applicationContextgetBean(shoppingCart);

  shoppingCartaddItem(aaa);

  shoppingCartaddItem(cdrw);

  shoppingCartaddItem(dvdrw);

  Cashier cashier = (Cashier) applicationContextgetBean(cashier);

  cashiercheckout(shoppingCart);

  }

  }

  注書上說如果使用JSR注解@PostConstruct和@PreDestroy並且一個CommonAnnotationBeanPostProcessor實例調用初始化方法那麼PathCheckingBeanPostProcessor不能正常工作因為它的默認優先級低於CommonAnnotationBeanPostProcessor經我實踐證明PathCheckingBeanPostProcessor仍然可以正常工作


From:http://tw.wingwit.com/Article/program/Java/ky/201311/27853.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.