zoukankan      html  css  js  c++  java
  • [译]10-Spring BeanPostProcessor

    Spring框架提供了BeanPostProcessor接口,该接口暴露了两个方法postProcessBeforeInitialization(Object bean,String beanName)

    和postProcessAfterInitialization(Object bean,String beanName).其中第一参数是经过实例化的bean实例,第二个参数是该bean在

    spring IOC容器中的唯一标识.

    通过实现BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法,我们可以做很多有意义的

    事情.postProcessBeforeInitialization方法的调用时机是在bean实例化并装配完毕之后,在调用初始化方法之前;而第二方法调用的时机

    是在初始化方法调用之后.为了便于理解,我画了一张图:

    通过上图可知,我们可以定义多个BeanPostProcessor接口的实现类,多个实现类直接以责任链的方式依次执行.

    一般情况下BeanPostProcessor的实现类还会实现org.springframework.core.Ordered接口,Ordered接口的定义了getOrder方法,该方

    法的返回值代表该BeanPostProcessor实现类的执行时机(数字越小,越先执行)

    我们下面写一段例子程序,以上图为原本.程序中会定义三个BeanPostProcessor,三个的作用如下:

    红色:LogRecorder,记录日志

    蓝色:TimeRecoder,记录执行时间记录

    紫色:PermissionCheck,权限检查

    1.新建com.tutorialspoint.post_processor包,并在包中新建HelloWorld.java类,类的内容如下:

    package com.tutorialspoint.post_processor;
    
    public class HelloWorld {
       
       public HelloWorld(){
           System.out.println("constructor invoked ... ");
       }
       private String message;
    
       public void setMessage(String message){
           System.out.println("set method invoked ... ");
          this.message  = message;
       }
    
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
    
       public void init(){
          System.out.println("init method invoked ... ");
       }
    
       public void destroy(){
          System.out.println("destroy method invoked ... ");
       }
    }

    2.在包com.tutorialspoint.post_processor中新建上述三个BeanPostProcessor的实现类,三个类的内容分别如下:

    LogRecorder.java

    package com.tutorialspoint.post_processor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;
    
    public class LogRecorder implements BeanPostProcessor,Ordered {
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            //初始化方法调用之后会回调该方法,在这里可以根据实际需求进行编码。
            System.out.println("Log Info:"+beanName+" has been initailized");
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            //初始化方法调用之前调用该方法.
            System.out.println("Log Info:"+beanName+" is going to be initailized");
            return bean;
        }
    
        //实现该方法用于指明该BeanPostProcessor的执行时机
        @Override
        public int getOrder() {
            return 1;
        }
    
    }

    TimeRecoder.java

    package com.tutorialspoint.post_processor;
    
    import java.util.Date;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;
    
    public class TimeRecoder implements BeanPostProcessor,Ordered{
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println(beanName+" has been initilized,time now is "+new Date());
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println(beanName+" is going to be initilized,time now is "+new Date());
            return bean;
        }
    
        @Override
        public int getOrder() {
            return 2;
        }
    
    }

    PermissionCheck.java

    package com.tutorialspoint.post_processor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;
    
    public class PermissionCheck implements BeanPostProcessor,Ordered {
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println(beanName+" has been initailized,permissions checked... ");
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println(beanName+" is going to be initailized,begin to check permissions ... ");
            return bean;
        }
    
        @Override
        public int getOrder() {
            return 3;
        }
    
    }

    3.在src目录下新建post_processor.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       
       <bean id="helloWorld" 
             class="com.tutorialspoint.post_processor.HelloWorld" 
             destroy-method="destroy"
             init-method="init">
           <property name="message" value="Hello World!"></property>
       </bean>
       
       <!-- spring容器会检测到实现了BeanPostProcessor接口的bean,并在适当的时机调用适当的方法 -->
       <bean name="logRecorder" class="com.tutorialspoint.post_processor.LogRecorder"></bean>
       
       <bean name="timeRecoder" class="com.tutorialspoint.post_processor.TimeRecoder"></bean>
       
       <bean name="permissionCheck" class="com.tutorialspoint.post_processor.PermissionCheck"></bean>
    
    </beans>

    4.在com.tutorialspoint.post_processor包中新建MainApp.java,内容如下:

    package com.tutorialspoint.post_processor;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
    
        public static void main(String[] args) {
            
            AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("post_processor.xml");
            HelloWorld hw = (HelloWorld)ctx.getBean("helloWorld");
            hw.getMessage();
            ctx.registerShutdownHook();
        }
    }

    5.运行程序,检查结果:

    仔细分析运行结果,跟我们预期是一致的!

  • 相关阅读:
    Stl源码剖析读书笔记之Alloc细节
    Lua热更系统
    Linux C++线程池
    linux sort,uniq,cut,wc.
    (转)Linux grep
    用LogParser分析IIS请求压力
    (转)MySQL主从复制的常见拓扑、原理分析以及如何提高主从复制的效率总
    AIS相关资料
    python学习笔记
    (转)MySQL InnoDB修复笔记
  • 原文地址:https://www.cnblogs.com/sysman/p/4479358.html
Copyright © 2011-2022 走看看