zl程序教程

您现在的位置是:首页 >  后端

当前栏目

8 -- 深入使用Spring -- 1...1Bean后处理器

Spring -- 深入 ... 处理器 使用
2023-09-11 14:14:57 时间

      8.1.1 Bean后处理器(BeanPostProcessor)

        Bean后处理器主要负责对容器中其他Bean执行后处理,例如为容器中的目标Bean生成代理等。

        Bean后处理器会在Bean实例创建成功之后,对Bean实例进行进一步的增强处理。

        Bean后处理器必须实现BeanPostProcessor接口,BeanPostProcessor接口包含如下两个方法:

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

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

        Demo-----------------

        Class : Chinese

package edu.pri.lime._8_1_1.bean.impl;

import org.springframework.beans.factory.InitializingBean;

import edu.pri.lime._8_1_1.bean.Axe;
import edu.pri.lime._8_1_1.bean.Person;

public class Chinese implements Person,InitializingBean{

    private String name;
    private Axe axe;

    public Chinese() {
        super();
        System.out.println("1.Spring 实例化主调Bean:Chinese实例。。。");
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        System.out.println("2.Spring 执行setName() 方法注入依赖关系。。。");
        this.name = name;
    }
    public Axe getAxe() {
        return axe;
    }
    public void setAxe(Axe axe) {
        System.out.println("2.Spring 执行setAxe() 方法注入依赖关系。。。");
        this.axe = axe;
    }
    public void afterPropertiesSet() throws Exception {
        System.out.println("4.1生命周期方法。。。");
    }

    public void init(){
        System.out.println("4.2生命周期方法。。。");
    }
    public void useAxe() {
        System.out.println(name + axe.chop());
    }
    
}

        Class : MyBeanPostProcessor

package edu.pri.lime._8_1_1;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import edu.pri.lime._8_1_1.bean.impl.Chinese;

public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * 对容器中Bean实例进行后处理
     * @param bean 需要进行后处理的原Bean实例
     * @param beanName 需要进行后处理的Bean的配置id
     * @return 返回后处理完成或测Bean
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3.Bean 后处理器在初始化之前对" + beanName + "进行增强处理。。。");
        //返回的处理或的Bean实例,该实例就是容器中实际使用的Bean
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("5.Bean 后处理器在初始化之后对" + beanName + "进行增强处理。。。");
        if(bean instanceof Chinese){
            Chinese chinese = (Chinese)bean;
            chinese.setName("Oracle");
        }
        return bean;
    }

}

        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="edu.pri.lime._8_1_1.bean.impl.Chinese" init-method="init">
        <property name="name" value="lime"/>
        <property name="axe" ref="steelAxe"/>
    </bean>
    
    <bean id="steelAxe" class="edu.pri.lime._8_1_1.bean.impl.SteelAxe"/>
    
    <!-- 配置Bean后处理器,可以无须指定id属性 -->
    <bean class="edu.pri.lime._8_1_1.MyBeanPostProcessor"/>

</beans>

        Class : BeanPostProcessorMain

package edu.pri.lime._8_1_1.bean.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import edu.pri.lime._8_1_1.bean.Person;
import edu.pri.lime._8_1_1.bean.impl.Chinese;

public class BeanPostProcessorMain {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("app_8_1_1.xml");
        Person person = ctx.getBean("chinese",Chinese.class);
        person.useAxe();
    }
}

        Console : 

1.Spring 实例化主调Bean:Chinese实例。。。
3.Bean 后处理器在初始化之前对steelAxe进行增强处理。。。
5.Bean 后处理器在初始化之后对steelAxe进行增强处理。。。
2.Spring 执行setName() 方法注入依赖关系。。。
2.Spring 执行setAxe() 方法注入依赖关系。。。
3.Bean 后处理器在初始化之前对chinese进行增强处理。。。
4.1生命周期方法。。。
4.2生命周期方法。。。
5.Bean 后处理器在初始化之后对chinese进行增强处理。。。
2.Spring 执行setName() 方法注入依赖关系。。。
Oracle使用钢斧砍材真快

        如果使用ApplicationContext作为Spring容器,Spring容器会自动检测容器中的所有Bean,如果发现某个Bean类实现了BeanPostProcessor接口,ApplicationContext 会自动将其注册为Bean后处理器。

        Bean后处理器两个方法的回调时机:

        如果使用BeanFactory作为Spring容器,则必须手动注册Bean后处理器,程序必须获取Bean后处理器实例,然后手动注册,这就需要在配置文件中为Bean处理器指定id属性。

            Resource isr = new ClassPathResource("app_8_1_1.xml");
            DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
            new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(isr);    
//            获取容器中的Bean后处理器
            BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp");
//            注册Bean后处理器
            beanFactory.addBeanPostProcessor(bp);
            Person per = (Person) beanFactory.getBean("chinese");
            per.useAxe();

啦啦啦