• spring-第十二篇之两种后处理器


    1、扩展IoC容器使用后处理器扩展

         bean后处理器:对容器中的bean进行后处理,也就是额外的加强。

         容器后处理:对IoC容器进行后处理,增强容器功能。

    2、bean后处理器

         负责处理容器中的所有bean。

         bean后处理器必须实现BeanPostProcessor接口,提供非方法有:

              Object postProcessBeforeInitialization(Object bean,String name)throws BenasException:该方法第一个参数是系统即将进行后处理的bean实例,第二个参数是bean的配置id。在目标bean初始化之前被回调。

              Object postProcessAfterInitialization(Object bean,String name)throws BenasException:该方法第一个参数是系统即将进行后处理的bean实例,第二个参数是bean的配置id。在目标bean初始化之后被回调。

          举个例子:

          

          MyBeanPostProcessor.java

    package com.lfy.bean;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
            
            System.out.println("bean后处理器在初始化之后对"+name+"进行增强处理...");
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
            
            System.out.println("bean后处理器在初始化之前对"+name+"进行增强处理...");
            return bean;
        }
    
    }

          Chinese.java

    package com.lfy.bean;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    public class Chinese implements InitializingBean,DisposableBean,BeanNameAware,ApplicationContextAware {
        
        private ApplicationContext ctx;
        private String beanID;
        private String someBodyName;
    
        public Chinese() {
            System.out.println("-----无参构造器-----");
        }
        
        @Override
        public void setApplicationContext(ApplicationContext ctx) throws BeansException {
            this.ctx=ctx;
            System.out.println("-----获取ApplicationContext容器ctx-----");
        }
    
        @Override
        public void setBeanName(String name) {
            this.beanID=name;
            System.out.println("-----获取bean id-----");
        }
        
        /**
         * 生命周期方法afterPropertiesSet
         */
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("-----依赖关系注入之后,生命周期方法afterPropertiesSet-----");
        }
        
        /**
         * 生命周期方法init
         */
        public void init() {
            System.out.println("-----依赖关系注入之后,生命周期方法init-----");
        }
    
        /**
         * 生命周期方法destory
         */
        @Override
        public void destroy() throws Exception {
            System.out.println("-----bean销毁之前destroy-----");
        }
        
        /**
         * 生命周期方法close
         */
        public void close() {
            System.out.println("-----bean销毁之前close-----");
        }
        
        /**
         * setter方法
         * @param name
         */
        public void setSomeBodyName(String name) {
            this.someBodyName=name;
            System.out.println("-----property注入属性setter方法-----"+someBodyName);
        }
    
    }

          beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
          
          <bean id="chinese" class="com.lfy.bean.Chinese" init-method="init" destroy-method="close">
             <property name="someBodyName" value="至尊宝"/>
          </bean>
          
          <bean class="com.lfy.bean.MyBeanPostProcessor"/>
    </beans>

          SpringTest.java

    package com.lfy.main;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.lfy.bean.Chinese;
    
    /**
     * 
     * @author lfy
     *
     */
    public class SpringTest {
    
        public static void main(String[] args) {
            
            AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
            
            Chinese chin=ctx.getBean("chinese", Chinese.class);
            
            ctx.registerShutdownHook();
            System.exit(0);
        }
    
    }

          运行结果:

          

         总结:容器会自动将实现了BeanPostProcessor接口的bean注册为后处理器。它们之间执行的先后顺序如上。后处理会在每个bean创建时自动执行。

         使用BeanFactory作为spring容器,必须手动注册后处理器。

         bean后处理器的用处:

             1》BeanNameAutoProxyCreator:根据bean实例的name属性,创建bean实例的代理。

             2》DefaultAdvisorAutoProxyCreator:根据提供的Advisor,对容器中的所有bean实例创建代理。

    3、容器后处理器

        负责处理容器本身。

        容器后处理器必须实现BeanFactoryPostProcessor接口,并实现postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),在该方法中对spring容器进行自定义扩展。使用BeanFactory的容器需要手动注册后处理bean。

        举个例子:

        

        MyContainerPostProcessor.java

    package com.lfy.bean;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    
    public class MyContainerPostProcessor implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("容器后处理器...spring容器是"+beanFactory);
        }
    
    }

         beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
          
          <!-- 遇到了个问题,destory-method="close"不能出现在<bean.../>,暂未明白原因  -->
          <bean id="chinese" class="com.lfy.bean.Chinese" init-method="init" destroy-method="close">
             <property name="someBodyName" value="至尊宝"/>
          </bean>
          
          <bean class="com.lfy.bean.MyBeanPostProcessor"/>
          <bean class="com.lfy.bean.MyContainerPostProcessor"/>
    </beans>

         运行结果:

        总结:如果有需要,可以配置多个容器后处理器,多个容器后处理器可设置order属性来控制容器后处理器的执行顺序,但需要容器后处理器实现Ordered接口。

  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/ZeroMZ/p/11332370.html
Copyright © 2020-2023  润新知