【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用

FactoryBean的应用实战

  1. 需要写一个A类来实现FactoryBean
  2. 实现FactoryBean的3个方法,即getOject(), getObjectType(), isSingleton()
  3. 注意:在通过xml的【 】标签或者通过注解方式将A类注入容器的时候,返回的实例不是A类,而是T类,因为他会自动的执行getObject()方法,而getObject()方法中new的是T类的对象,所以这块不要搞错了
  4. 下面代码案例: 有xml配置可见,bean注入的是MyFactoryBean, 但图中可以看出实例出来的却是ObjectBean类型的,

implements FactoryBean代码:

package com.spring.factoryBean实战;
import org.springframework.beans.factory.FactoryBean;
public class myFactoryBean implements FactoryBean {
    @Override
    public ObjectBean getObject() throws Exception {
        return new ObjectBean("hbz", 26);
    }
    @Override
    public Class getObjectType() {
        return null;
	}
}

xml配置文件代码:




    

【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用_第1张图片

BeanFactroyPostProcessor的应用实战

  1. BeanFactroyPostProcessor 会在 BeanPostProcessor之前执行, 即先执行BeanFactroyPostProcessor
  2. 作用:读取应用程序上下文,并对其属性进行修改, 可以修改BeanDefinition中的属性,比如设置单例多例(setScope), 是否是懒加载(setLazyInit()), 动态设置初始化方法等
  3. 执行BeanFactroyPostProcessor时还没有进行指定类的初始化(还未执行构造函数),所以通过BeanFactroyPostProcessor可以改变目标类属性
  4. 代码实战:
    FactoryBeanPostPorcess代码:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFacotryPostProcess implements BeanFactoryPostProcessor {

    public MyBeanFacotryPostProcess() {
        System.out.println("构造函数执行--------------------------");
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

        // 获取所有的bean
        String[] beanDefinitionNames = configurableListableBeanFactory.getBeanDefinitionNames();
        for(String befinitonName : beanDefinitionNames){
            if("productService".equalsIgnoreCase(befinitonName)){
                BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(befinitonName);
                // 单例多例
                beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
                // 设置初始化方法
                beanDefinition.setInitMethodName("testInit");
            }
        }
    }
}

xml配置类代码:





    


    

目标类代码:

package com.spring.beanFactoryPostProcess实战;

public class ProductServiceImpl implements ProductService{

    public ProductServiceImpl(){
        System.out.println("这个是构造函数");
    }

    @Override
    public void example() {
        System.out.println("类名: "+ this.getClass().toString());
    }


    public void testInit(){
        System.out.println("这个是初始化方法");
    }
}

输出结果:
【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用_第2张图片

BeanPostProcessor的应用

  1. BeanPostProcessor在BeanFactoryPostProcessor之后执行
  2. BeanPostProcessor作用于bean实例化过程中, 可以改变bean实例中的属性值, 比如bean中有个name = “123”, 则可以在BeanPostProcessor的两个实现方法中将其改成setName(“456”)
  3. BeanPostProcessor通常需要实现两个方法,分别是postProcessBeforeInitialization, postProcessAfterInitialization
  4. postProcessBeforeInitialization: 在目标类的【初始化方法】之前执行。postProcessAfterInitialization:在目标类【初始化方法之后】执行
  5. postProcessBeforeInitialization,postProcessAfterInitialization都会有个参数,叫【String beanName】, 这个beanName是容器中所有的bean(即容器有多少个bean,这俩方法就走多少遍),如果想在指定目标类触发BeanPostProcessor,则需要加一个判断。如果在xml定义了bean,则使用xml中定义的name去和beanName作比较,如果不是在xml中定义的,是new出来的,直接用目标类的【类名(首字母小写)】去和beanName比较,默认new出来的beanName就等于类名首字母小写
  6. 代码:

BeanPostProcessor实现类:

package com.spring.beanPostProcessor实战;

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

public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * 在每个bean初始化方法之前执行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("MyBeanPostProcessor # BeforeInitialization 调用 beanName = " + beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    /**
     * 在每个bean初始化方法之后执行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("MyBeanPostProcessor # AfterInitialization 调用 beanName = " + beanName);
        
        // 判断beanName,如果beanName = productBeanService, 则就执行如下操作
        if("productBeanService".equalsIgnoreCase(beanName)){
            ProductBeanServiceImpl productBeanService = (ProductBeanServiceImpl) bean;
            productBeanService.setName("v2.修改后的值");
            BeanPostProcessor.super.postProcessAfterInitialization(productBeanService, beanName);
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

xml配置代码:





    

    

目标类代码:

package com.spring.beanPostProcessor实战;

import org.springframework.beans.factory.InitializingBean;


/**
 * 实现InitializingBean就可以实现初始化方法,因为InitializingBean中的afterPropertiesSet就是初始化方法,无需通过xml指定
 */
public class ProductBeanServiceImpl implements ProductBeanService, InitializingBean {

    private String name = "v1.修改之前的值";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ProductBeanServiceImpl(){
        System.out.println("这个是构造函数");
    }

    @Override
    public void example() {
        System.out.println("类名: "+ this.getClass().toString());
    }

    /**
     * BeanPostProcessor中的postProcessBeforeInitialization方法会在该初始化方法之前执行
     * BeanPostProcessor中的postProcessAfterInitialization方法会在该初始化方法之后执行
     *
     */
    public void testInit(){
        System.out.println("这是在xml或者BeanFactoryPostProcess中指定的初始化方法");
    }

    /**
     * 这个也是初始化方法,但必须实现InitializingBean
     * 效果: 和testInit()一摸一样,该方法不需要在xml中配置,而testInit需要在xml或者通过BeanFactoryPostProcess配置并指定testInit初始化方法才可以
     *
     *
     * BeanPostProcessor中的postProcessBeforeInitialization方法会在该初始化方法之前执行
     * BeanPostProcessor中的postProcessAfterInitialization方法会在该初始化方法之后执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("这是InitializingBean的初始化方法");
    }
}

启动类代码:

package com.spring.beanPostProcessor实战;

import com.spring.beanFactoryPostProcess实战.ProductServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {

        // 读取指定的配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:beanPostPorcessor.xml");
        ProductBeanServiceImpl productBeanService = (ProductBeanServiceImpl) context.getBean("productBeanService");
        System.out.println(productBeanService);
    }
}

执行结果截图:
【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用_第3张图片

你可能感兴趣的:(java,spring,开发语言)