zoukankan      html  css  js  c++  java
  • Spring中常用重要的接口

    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());
    	}
    	
    	@Override
    	public String toString() {
    		return "User [name=" + name + ", age=" + age + "]";
    	}
    
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		// TODO Auto-generated method stub
    		System.out.println("This is the post before..............");
    		return bean;
    	}
    
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		// TODO Auto-generated method stub
    		System.out.println("This is the post after..............");
    		return bean;
    	}
    
    	@Override
    	public void afterPropertiesSet() throws Exception {
    		// TODO Auto-generated method stub
    		System.out.println("this is InitializingBean method..."
    				+ "(called by before init method, after set property values)."+this.getAge());
    	}
    
    	@Override
    	public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    		// TODO Auto-generated method stub
    		System.out.println("this is DestructionAwareBeanPostProcessor, called when destroy bean...");
    	}
    	
    	public void destroy()
    	{
    		System.out.println("this is destroy method....");
    	}
    
    	@Override
    	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    		// TODO Auto-generated method stub
    		this.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           

     

  • 相关阅读:
    log记录日志使用说明
    浅谈WebService开发三(动态调用WebService)转
    浅谈WebService开发二(同步与异步调用)转
    浅谈WebService开发(一)转
    Log4net使用(二)
    Log4net使用(一)
    创建DSN
    Oracle的substr函数简单用法(转)
    医院里的CR、DR、CT、磁共振、B超都是什么?
    lambda表达式(2)
  • 原文地址:https://www.cnblogs.com/daxiong225/p/9571354.html
Copyright © 2011-2022 走看看