在bean对象初始化之前和之后 (bean从容器中返回给我们之前): 来做某些事情
// 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是在bean初始化前后来做事情
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
自定义的组件(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