Spring BeanPostProcessor接口使用详解

Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor、BeanFactoryPostProcessor、BeanValidationPostProcessor等一系列后处理器。他们的使用方式大多类似,了解其中一个并掌握他的使用方式,其他的可以触类旁通。

这里以BeanPostProcessor为例展示其使用方式。

BeanPostProcessor接口提供了两个供开发者自定义的方法:postProcessBeforeInitialization、postProcessAfterInitialization。

postProcessBeforeInitialization:该方法主要针对spring在bean初始化时调用初始化方法前进行自定义处理。

postProcessAfterInitialization:该方法主要针对spring在bean初始化时调用初始化方法后进行自定义处理。

示例代码:

/**
 * 测试bean
 */
public class Cat {
  private String name;
  private int age;
  public void say() {
    System.out.println("name:" + name);
    System.out.println("age:" + age);
  }

  public String getName() {
    return name;
  }

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

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }
}
/**
 * 自定义后处理器
 */
public class CatBeanPostProcessor implements BeanPostProcessor {

  @Nullable
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Cat) {
      //输出原始属性
      Cat cat = (Cat) bean;
      cat.say();
      return bean;
    }
    return bean;
  }

  @Nullable
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Cat) {
      //修改属性值,并返回
      Cat cat = (Cat) bean;
      cat.setName("hello maomi");
      cat.setAge(3);
      return cat;
    }
    return bean;
  }
}
/**
 * 运行
 */
public class Run {
  public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
    Cat cat = (Cat) applicationContext.getBean("cat");
    cat.say();
  }
}

xml配置信息

  <!--配置bean并初始化-->
  <bean id="cat" class="com.source.postprocessor.Cat" >
    <property name="name" value="HelloKitty" />
    <property name="age" value="1" />
  </bean>

  <bean id="catBeanPostProcessor" class="com.source.postprocessor.CatBeanPostProcessor" />

输出结果:

name:HelloKitty
age:1
name:hello maomi
age:3

可以看到通过后处理器处理过后的bean信息已经改变。最后,看看源码中如何调用自定义实现的。

在初始化bean方法中:AbstractAutowireCapableBeanFactory.java

  /**
  * 初始化bean
  */
 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   //省略部分无关代码
   Object wrappedBean = bean;
   //初始化前
   if (mbd == null || !mbd.isSynthetic()) {
     wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
     //调用初始化方法初始化bean
     invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
     throw new BeanCreationException(
         (mbd != null ? mbd.getResourceDescription() : null),
         beanName, "Invocation of init method failed", ex);
   }
   //初始化后
   if (mbd == null || !mbd.isSynthetic()) {
     wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
 }
 //postProcessBeforeInitialization方法调用
 @Override
 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
     throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
     //调用自定义postProcessBeforeInitialization方法
     Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
     if (current == null) {
       return result;
     }
     result = current;
   }
   return result;
 }
 //postProcessAfterInitialization方法调用
 @Override
 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
     throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
     //自定义postProcessAfterInitialization方法调用
     Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
     if (current == null) {
       return result;
     }
     result = current;
   }
   return result;
 }

以上就是spring对自定义方法实现的调用过程。希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 解析Java的Spring框架的BeanPostProcessor发布处理器
(0)

相关推荐

  • 解析Java的Spring框架的BeanPostProcessor发布处理器

    BeanPostProcessor 的接口定义,可以实现提供自己的实例化逻辑,依赖解析逻辑等,也可以以后在Spring容器实例化完毕,配置和初始化一个bean通过插入一个或多个的BeanPostProcessor实现一些自定义逻辑回调方法实现. 可以配置多个的BeanPostProcessor接口,控制这些的BeanPostProcessor接口,通过设置属性顺序执行顺序提供的BeanPostProcessor实现了Ordered接口. BeanPostProcessor可以对bean(或对象)

  • Spring BeanPostProcessor接口使用详解

    Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor.BeanFactoryPostProcessor.BeanValidationPostProcessor等一系列后处理器.他们的使用方式大多类似,了解其中一个并掌握他的使用方式,其他的可以触类旁通. 这里以BeanPostProcessor为例展示其使用方式. BeanPostProcessor接口提供了两个供开发者自定义的方法:postProcessBeforeInitializati

  • java中Spring Security的实例详解

    java中Spring Security的实例详解 spring security是一个多方面的安全认证框架,提供了基于JavaEE规范的完整的安全认证解决方案.并且可以很好与目前主流的认证框架(如CAS,中央授权系统)集成.使用spring security的初衷是解决不同用户登录不同应用程序的权限问题,说到权限包括两部分:认证和授权.认证是告诉系统你是谁,授权是指知道你是谁后是否有权限访问系统(授权后一般会在服务端创建一个token,之后用这个token进行后续行为的交互). spring

  • Spring Java-based容器配置详解

    装Java-based的配置 使用 @Import 注解 跟在Spring XML文件中使用<import>元素添加模块化的配置类似,@Import注解允许你加载其他配置类中的@Bean定义: @Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public

  • Spring AOP 基于注解详解及实例代码

    Spring AOP  基于注解详解及实例代码 1.启用spring对@AspectJ注解的支持: <beans xmlns:aop="http://www.springframework.org/schema/aop"...> <!--启动支持--> <aop:aspectj-autoproxy /> </beans> 也可以配置AnnotationAwareAspectJAutoProxyCreator Bean来启动Spring对@

  • spring结合hibernate示例详解

    单纯Hibernate程序 1.首先是导入hibernate的jar包. 2. 建立用户和用户操作记录实体,Log.Java和User.java.代码如下所示. Log.java import java.util.Date; public class Log { private int id; //日志的类别.日志一般起到一个不可否认性. //操作日志 安全日志 事件日志. private String type; private String detail; private Date time

  • Spring @Transactional工作原理详解

    本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的.之后的文章将介绍: propagation(事务传播)和isolation(隔离性)等属性的使用 事务使用的陷阱有哪些以及如何避免 JPA和事务管理 很重要的一点是JPA本身并不提供任何类型的声明式事务管理.如果在依赖注入容器之外使用JPA,事务处理必须由开发人员编程实现. UserTransaction utx = entityManager.getTransaction(); try{ utx.be

  • Spring 缓存抽象示例详解

    Spring缓存抽象概述 Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成. Cache接口为缓存的组件规范定义,包含缓存的各种操作集合: Cache接口下Spring提供了各种xxxCache的实现:如RedisCache,EhCacheCache , ConcurrentMapCa

  • Spring ApplicationListener监听器用法详解

    这篇文章主要介绍了Spring ApplicationListener监听器用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 监听器在使用过程中可以监听到某一事件的发生,进而对事件做出相应的处理. 首先自定义一个监听器myListener实现ApplicationListener接口 @Repository public class myListener implements ApplicationListener<Application

  • Spring ApplicationListener的使用详解

    介绍 Spring ApplicationListener 是Spring事件机制的一部分,与ApplicationEvent抽象类结合完成ApplicationContext的事件通知机制. ContextRefreshedEvent事件监听 以Spring的内置事件ContextRefreshedEvent为例,当ApplicationContext被初始化或刷新时,会触发ContextRefreshedEvent事件.如下代码示例: @Component public class Lear

  • Spring Cloud Ribbon配置详解

    本节我们主要介绍 Ribbon 的一些常用配置和配置 Ribbon 的两种方式. 常用配置 1. 禁用 Eureka 当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡. 这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,如果我们不想和 Eureka 集成,可以通过下面的配置方法将其禁用. # 禁用 Eureka ribbon.eureka.enabled=false 当我们禁用了 Eure

随机推荐