Bean的后处理

Bean的后处理

  • BeanPostProcessor的用法
    bean级别的处理,针对某个具体的bean进行处理,接口提供了两个方法,分别是bean初始化前和bean初始化后执行方法。
    postProcessBeforeInitialization:该方法主要针对spring在bean初始化时调用初始化方法前进行自定义处理。
    postProcessAfterInitialization:该方法主要针对spring在bean初始化时调用初始化方法后进行自定义处理。
  • 自定义BeanPostProcessor
    bean:
@Data
public class Cat {
  private String name;
  private int age;
  public void say() {
    System.out.println("name:" + name);
    System.out.println("age:" + age);
  }
}

自定义BeanPostProcessor:

/**
 * 自定义BeanPostProcessor后处理器
 */
public class CatBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Cat) {
      System.out.println("bean Cat初始化之前...");
      //输出原始属性
      Cat cat = (Cat) bean;
      cat.say();
      return bean;
    }
    return bean;
  }
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Cat) {
      System.out.println("bean Cat初始化之后...");
      //修改属性值,并返回
      Cat cat = (Cat) bean;
      cat.setName("hello maomi");
      cat.setAge(3);
      return cat;
    }
    return bean;
  }
}

配置文件:

    <!--自定义BeanPostProcessor的测试-->
    <!--配置bean并初始化-->
    <bean id="cat" class="com.example.test.demo.spring.BeanPostProcessor.Cat" >
        <property name="name" value="HelloKitty" />
        <property name="age" value="1" />
    </bean>
    <bean id="catBeanPostProcessor" class="com.example.test.demo.spring.BeanPostProcessor.CatBeanPostProcessor" />

测试:

        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:conf/application.xml");
        Cat bean = context.getBean(Cat.class);
        bean.say();
bean Cat初始化之前...
name:HelloKitty
age:1
bean Cat初始化之后...
name:hello maomi
age:3

BeanPostProcessor原理:

populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值的

initializeBean(beanName, exposedObject, mbd){
   applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   invokeInitMethods(beanName, wrappedBean, mbd);//执行自定义初始化方法
   applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

applyBeanPostProcessorsBeforeInitialization:
遍历容器中所有的BeanPostProcessor:挨个执行PostProcessorsBeforeInitialization,一旦返回null,就跳出for循环,不会执行后面的BeanPostProcessor.PostProcessorsBeforeInitialization

Spring底层对BeanPostProcessor的使用:
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等都是使用BeanPostProcessor实现的。

例如:组件里注入ioc容器。
组件实现ApplicationContextAware 即可。
ApplicationContextAwareProcessor(BeanPostProcessor的一个实现类)的postProcessBeforeInitialization方法判断当前bean是不是实现了ApplicationContextAware ,是的话,调用bean的set方法,((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);

@Component
public class Dog  implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
    public Dog() {
        System.out.println("dog...constructor...");
    }
    //对象创建并赋值之后调用初始化
    @PostConstruct
    public void init() {
        System.out.println("Dog...@PostConstruct...");
    }
    //容器移除对象之前调用销毁
    @PreDestroy
    public void destroy() {
        System.out.println("Dog ...@PreDestroy...");
    }
}

其他BeanPostProcessor实现类:
BeanValidationPostProcessor:数据校验的,当对象创建完,给JavaBean赋值还可以做数据校验;
InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct以及@PreDestroy注解的。(使用反射执行的注解标注的方法)
AutowiredAnnotationBeanPostProcessor :处理@Autowired注解,在对象创建完后,处理被@Autowired注解标注的属性

BeanPostProcessor与BeanFactoryPostProcessor的区别

BeanPostProcessor:bean级别的处理,针对某个具体的bean进行处理。
执行时机:
实例化bean之后执行,接口提供了两个方法,分别是bean初始化前和bean初始化后执行方法。

BeanFactoryPostProcessor:BeanFactory级别的处理,是针对整个Bean的工厂 进行处理。
执行时机:
接口提供postProcessBeanFactory方法,可以在当前BeanFactory初始化后,beanDefinition已经loaded,但是bean还未创建前 进行调用,也就是,bean实例化之前执行,可以修改bean的定义属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值