BeanPostProcessor后置处理器

后置处理 Bean : BeanPostProcessor的使用

在bean对象初始化之前和之后 (bean从容器中返回给我们之前): 来做某些事情

  • BeanPostProcessor 作用:对 Spring 工厂所创建的对象,进行再加工。(AOP 的底层实现)
  • 后置处理 Bean 原理分析
  • 程序员实现 BeanPostProcessor 接口中规定的两个方法:
// bean初始化之前调用
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    return bean;
}

作用:Spring 创建完对象,并进行注入后,可以运行 Before ⽅法进行加工;

通过方法的参数获得 Spring 创建好的对象,最终通过返回值交给 Spring 框架。

// bean初始化之后调用
public Object postProcessAfterInitialization(Object bean, String beanName) {
    return bean;
}

作⽤:Spring 执行完对象的初始化操作后,可以运行 After ⽅法进行加工;

通过方法的参数获得 Spring 创建好的对象,最终通过返回值交给 Spring 框架。
实战中:很少处理 Spring 的初始化操作,没有必要区分 Before,After。只需要实现其中一个,建议是 After 方法即可。

BeanPostProcessor 开发步骤

类实现 BeanPostProcessor 接口


// 在初始化方法之前和之后执行下面两个方法
//@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Category category = (Category) bean;
        category.setName("yusael");
        return category;
    }

}

Spring 配置文件中进行配置

  • 细节:BeanPostProcessor 会对 Spring 工厂创建的所有对象进行加工。如果工厂创建了多个不同的对象,要注意区别传入的对象:
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof  Category) {
        Category category = (Category) bean;
        category.setName("yusael");
        return category;
    }
    return bean;
}

BeanPostProcessor后置处理器_第1张图片

BeanPostProcessor后置处理器_第2张图片

BeanPostProcessor原理

下面代码可以证明:BeanPostProcessor是在bean初始化前后来做事情

这块代码在initializeBean方法内
BeanPostProcessor后置处理器_第3张图片

  • 在applyBeanProcessorsBeforeInitialization方法中遍历所有的BeanPostProcessor(包括实现类); 如果返回null, 表示不会执行后面的BeanPostProcessor了; 把所有的BPP在bean初始化之前的操作都执行完
    BeanPostProcessor后置处理器_第4张图片
  • 执行自定义初始化操作 invokeInitMethods方法
  • 在applyBeanProcessorsAfternitialization方法中遍历所有的BeanPostProcessor(包括实现类); 如果返回null, 表示不会执行后面的BeanPostProcessor了; 把所有的BPP在bean初始化之后的操作都执行完

BeanPostProcessor原理
BeanPostProcessor后置处理器_第5张图片

BeanPostProcessor在Spring底层的使用

BeanPostProcessor后置处理器_第6张图片

ApplicationContextAwareProcessor

  • class ApplicationContextAwareProcessor implements BeanPostProcessor

该processor给ApplicationContextAware接口导入了Spring中所有的bean; 我们实现ApplicationContextAware就可以拿到Spring容器中所有的bean

ApplicationContextAwareProcessor会在

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
	}


	@Override
	@Nullable // 在bean初始化之前来执行
	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						// 首先判断bean是否实现了ApplicationContextAware
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			// ... 省略
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			// 然后把这个bean转换为ApplicationContextAware, 将IoC容器
//			(this.applicationContext)设置到setApplicationContext()中
			// 所以在我们类实现ApplicationContextAware接口的实现方法中,拿到IoC容器
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}
}

测试

@Component
public class User implements ApplicationContextAware {
    private ApplicationContext ac;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ac = applicationContext;
    }

    public ApplicationContext getContext() {
        return ac;
    }

    public <Y> Y getBean(Class<Y> clazz) {
        return ac.getBean(clazz);
    }
}
    @Test
    public void test() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig6.class);
//        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
//        for (String name : beanDefinitionNames) {
//            System.out.println(name);
//        }
//        System.out.println(ac.getBean("rainBow"));

        User user = ac.getBean(User.class);
        ApplicationContext context = user.getContext();
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        System.out.println("-----------------------------");
        Red bean = user.getBean(Red.class);
        System.out.println(bean);
    }


org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig6
customer
user
red
blue
rainBow
-----------------------------
com.baizhiedu.bean.Red@6c4980d3

除了上面的ApplicationContextAwareProcessor; 还有给bean赋值, 注入其他组件, @Autowird, 生命周期注解, @Async 等 实现的原理; 都是采用xxxBeanPostProcessor来实现的

实现XxxAware, 使用Spring容器底层的一些组件

自定义的组件(bean) 想要使用Spring容器底层的一些组件(ApplicationContext, BeanFactory…等);

  • 我们自定义的组件 实现XxxAware; 实现他们的一些接口方法,
    在创建自定义组件对象的时候, 会调用接口规定的方法注入相关组件

实现XxxAware, 把Spring底层的一些组件注入到自定义的Bean中

@Component
public class TestAware implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

    private ApplicationContext applicationContext;

    // 将当前bean的名字返回
    @Override
    public void setBeanName(String s) {
        System.out.printf("当前bean的名字:%s%n", s);
    }

    // 返回IoC容器
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("IoC容器:" + this.applicationContext);
    }

    // 用来解析Spring中表达式的
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        System.out.println(resolver.resolveStringValue("你好, ${os.name}, my age is #{2 * 12}"));
    }
}
@Test
public void test02() {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig7.class);
    TestAware bean = ac.getBean(TestAware.class);
    System.out.println(bean);
}
当前bean的名字:testAware
你好, Mac OS X, my age is 24
IoC容器:org.springframework.context.annotation.AnnotationConfigApplicationContext@7714e963, started on Fri Apr 15 17:49:02 CST 2022

从下面图可以看出, 在bean返回之前就做了对应的处理工作
BeanPostProcessor后置处理器_第7张图片

你可能感兴趣的:(#,Spring,Spring,后置处理器)