• (008)spring之BeanPostProcessor的执行时机及作用


      BeanPostProcessor是一个接口,有两个方法:postProcessBeforeInitialization、postProcessAfterInitialization,这两个方法每个bean创建都会执行一次。

      postProcessBeforeInitialization在属性设置后,init方法执行前执行,postProcessAfterInitialization在属性设置后,init方法执行后执行。请看示例:

      pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.edu.spring</groupId>
        <artifactId>spring</artifactId>
        <version>1.0.0</version>
    
        <name>spring</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
        
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.2.RELEASE</version>
            </dependency>
        </dependencies>
    
    </project>
    View Code

      User.java

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    
    public class User {
    
    private ApplicationContext applicationContext;
        
        public void init(){
            System.out.println("User init()");
        }
        public void show(){
            System.out.println("User show(): "+applicationContext);
        }
        
        @Autowired
        public void setApplicationContext(ApplicationContext applicationContext) {
            System.out.println("------set()-----");
            this.applicationContext = applicationContext;
        }
        
    }
    View Code

      MyConfig.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyConfig {
    
        @Bean(initMethod="init")
        public User createUser(){
            return new User();
        }
    }
    View Code

      EchoBeanPostProcssor.java

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
     
    @Component
    public class EchoBeanPostProcssor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessBeforeInitialization-------------"+bean.getClass());
            return bean;
        }
    
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessAfterInitialization-------------"+bean.getClass());
            return bean;
        }
    
    }
    View Code

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext("com.edu.spring");
            context.getBean("createUser",User.class).show();
            context.close();
        }
    }
    View Code

      运行结果如下:

       这两个方法中都不能返回null,否则bean不会创建成功,如下:

      EchoBeanPostProcssor.java 中postProcessBeforeInitialization方法返回null

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
     
    @Component
    public class EchoBeanPostProcssor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessBeforeInitialization-------------"+bean.getClass());
            if(bean instanceof User){
                return null;
            }
            return bean;
        }
    
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessAfterInitialization-------------"+bean.getClass());
            return bean;
        }
    
    }
    View Code

      运行结果如下:

       EchoBeanPostProcssor.java 中postProcessAfterInitialization方法返回null

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
     
    @Component
    public class EchoBeanPostProcssor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessBeforeInitialization-------------"+bean.getClass());
            return bean;
        }
    
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessAfterInitialization-------------"+bean.getClass());
            if(bean instanceof User){
                return null;
            }
            return bean;
        }
    
    }
    View Code

      运行结果如下:

       BeanPostProcessor接口的作用,可以产生代理对象,实现回调,如添加日志等,如下:

      LogUser.java

    package com.edu.spring;
    
    public class LogUser extends User {
    
        public void show(){
            System.out.println("LogUser start");
            super.show();
            System.out.println("LogUser end");
        }
    }
    View Code

      EchoBeanPostProcssor.java

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
     
    @Component
    public class EchoBeanPostProcssor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessBeforeInitialization-------------"+bean.getClass());
            if(bean instanceof User){
                return new LogUser();
            }
            return bean;
        }
    
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("-------------postProcessAfterInitialization-------------"+bean.getClass());
            return bean;
        }
    
    }
    View Code

      运行结果如下:

       利用BeanPostProcessor模拟实现注入ApplicationContext对象

      SpringContextAware.java

    package com.edu.spring;
    
    import org.springframework.context.ApplicationContext;
    
    public interface SpringContextAware {
        public void setApplicationContext(ApplicationContext applicationContext);
    }
    View Code

      Dog.java

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Dog implements SpringContextAware {
    
    
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            // TODO Auto-generated method stub
            this.applicationContext=applicationContext;
        }
        
        public void show(){
            System.out.println("Dog :"+applicationContext.getClass());
        }
    }
    View Code

      ContextBeanPostProcessor.java

    package com.edu.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ContextBeanPostProcessor implements BeanPostProcessor {
    
        @Autowired
        private ApplicationContext applicationContext;
        
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            if(bean instanceof SpringContextAware){
                SpringContextAware sa=(SpringContextAware)bean;
                sa.setApplicationContext(applicationContext);
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            // TODO Auto-generated method stub
            return bean;
        }
    
    }
    View Code

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext("com.edu.spring");
            context.getBean("dog",Dog.class).show();
            context.close();
        }
    }
    View Code

      运行结果如下:

      

  • 相关阅读:
    Hack The Box——Monteverde
    【LeetCode】173.二叉搜索树迭代器(Java实现,两种方法)
    【LeetCode】98. 验证二叉搜索树(递归+中序遍历,Java实现,上下界详细图解)
    ERP-非财务人员的财务培训教(五)------资本结构筹划
    ERP-非财务人员的财务培训教(四)------公司/部门的成本与费用控制
    ERP-非财务人员的财务培训教(三)------公司/部门预算编制与评价
    ERP-非财务人员的财务培训教(二)------如何评价公司/部门经营业绩
    ERP-非财务人员的财务培训教(一.二)------财务基础知识
    ERP-非财务人员的财务培训教(一.一)------基本会计知识
    Oracle E-Business Suite Maintenance Guide Release 12.2(Patching Procedures)
  • 原文地址:https://www.cnblogs.com/javasl/p/11783488.html
Copyright © 2020-2023  润新知