標籤:val whether port nbsp read throws cts ase 擷取
Spring (ApplicationContext 初始化Bean的方法 refresh())
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.//建立Bean並post等方法registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset ‘active‘ flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
Spring 架構中想自己在bean的初始化階段自訂一些邏輯,或者想擷取一些資源,非常有用的介面有
BeanPostProcessor,// properties 設定完成,InitializingBean的 afterPropertiesSet(), init-method完成後對bean進行一些邏輯處理
InitializingBean,// 提供afterPropertiesSet(),位於init-method之前調用(這兩方法都可用於實現bean init方法);
DestructionAwareBeanPostProcessor,//postProcessBeforeDestruction(Object bean, String beanName) 方法於 destory方法之前調用;
BeanFactoryAware // setBeanFactory(BeanFactory beanFactory) 介面使Bean初始化完成後擷取BeanFactory資源,以便操作。類似的還有ApplicationContextAware....
public interface BeanPostProcessor { /**property values已經設定完成, * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean * initialization callbacks (like InitializingBean‘s <code>afterPropertiesSet</code> * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; if * <code>null</code>, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */ Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean * initialization callbacks (like InitializingBean‘s <code>afterPropertiesSet</code> * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding <code>bean instanceof FactoryBean</code> checks. * <p>This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other BeanPostProcessor callbacks. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; if * <code>null</code>, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}
/**已經完成了property 填充(完成InitializingBean 介面的afterPropertiesSet()調用,如果指定init-method 方法,也已經完成的調用(after..()之後))
* Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be <code>null</code>, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//調用BeanPostProcessor的before方法 } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//調用
BeanPostProcessor的after方法
} return wrappedBean; }
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("spring.xml"));
bf 只是儲存一些BeanDeinationMap, 並不會馬上執行個體化,需要後續調用getBean才初始化:
ApplicationContext ac2 = new ClassPathXmlApplicationContext("spring.xml");
ac2 會馬上將spring.xml中定義的bean執行個體化加到factory的緩衝中。
例子用ApplicationContext :
spring.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd "> <alias name="user" alias="testxx"/> <bean id="father" abstract="true"> <property name="local" value="Us"/> </bean> <bean id="user" class="com.donghua.bean.User" parent="father"> <property name="name" value="Allen"/> <property name="age" value="6"/> </bean> <bean id="user3" class="com.donghua.bean.User3" init-method="myInit" destroy-method="destroy"> <property name="name" value="Allen3"/> <property name="age" value="61"/> </bean> <bean id="factory" class="com.donghua.bean.MyBeanFactory"/></beans>
User3:
package com.donghua.bean;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;public class User3 implements BeanPostProcessor, InitializingBean, DestructionAwareBeanPostProcessor,BeanFactoryAware{BeanFactory beanFactory;private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void myInit(){System.out.println("this is my init....."+this.getAge());}@Overridepublic String toString() {return "User [name=" + name + ", age=" + age + "]";}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("This is the post before..............");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("This is the post after..............");return bean;}@Overridepublic void afterPropertiesSet() throws Exception {// TODO Auto-generated method stubSystem.out.println("this is InitializingBean method..."+ "(called by before init method, after set property values)."+this.getAge());}@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("this is DestructionAwareBeanPostProcessor, called when destroy bean...");}public void destroy(){System.out.println("this is destroy method....");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {// TODO Auto-generated method stubthis.beanFactory = beanFactory;}public void getUser2(){User u =(User) beanFactory.getBean("user");System.out.println(u.toString()+" this is user2...");}}
package com.donghua.test;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import com.donghua.anotation.User2;import com.donghua.bean.MyBeanFactory;import com.donghua.bean.User;import com.donghua.bean.User3;public class Test {public static void main(String[] args) {ApplicationContext ac2 = new ClassPathXmlApplicationContext("spring.xml");User3 u3 = (User3) ac2.getBean("user3");System.out.println(u3);u3.getUser2();((ClassPathXmlApplicationContext) ac2).close(); }}
輸出順序:
this is InitializingBean method...(called by before init method, after set property values).61 //InitializingBean
this is my init.....61 //init-method
This is the post before.............. //BeanPostProcesser
This is the post after..............
This is the post before..............
This is the post after..............
User [name=Allen3, age=61]
User [name=Allen, age=6] this is user2...
this is DestructionAwareBeanPostProcessor, called when destroy bean... // DestructionAwareBeanPostProcessor
this is DestructionAwareBeanPostProcessor, called when destroy bean...
this is destroy method.... //destory method
Spring中常用重要的介面