在其中:
4能获取BeanFactory(DefaultListableBeanFactory),5能获取ApplicationContext(DefaultListableBeanFactory)
你会发现,他们获取的都是同一个!
@Component
public class BeanFactoryUtil implements BeanFactoryAware {
private static BeanFactory beanFactory;
public static BeanFactory getBeanFactory() {
return beanFactory;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("调用了setBeanFactory");
setFactory(beanFactory);
}
private static void setFactory(BeanFactory bf) {
beanFactory = bf;
}
}
@SpringBootTest
class BeanFactoryUtilTest {
@Test
void getBeanFactory() {
System.out.println("===========" + BeanFactoryUtil.getBeanFactory().getClass().getSimpleName());
}
}
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(@NotNull ApplicationContext context) {
System.out.println("调用了setApplicationContext");
setContext(context);
}
private static void setContext(@NotNull ApplicationContext ac) {
context = ac;
}
public static ApplicationContext getContext() {
return context;
}
}
@SpringBootTest
class ApplicationContextUtilTest {
@Test
void getContext() {
System.out.println("===========" + ApplicationContextUtil.getContext().getClass().getSimpleName());
}
}
这个DefaultListableBeanFactory可以理解为整个spring IOC容器的始祖
6和8的话能做一个bean实例化之后的操作,比如动态代理:
public interface BeanPostProcessor {
// 这个方法会在bean实例化后,调用初始化方法之前执行
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 这个方法会在bean实例化后,调用初始化方法之后执行
// 这里的before和after是相对于初始化方法的调用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
我们知道往往大哥注解就可以让一个普通的类在运行时期变成动态代理类,比如说@Transcational
本来是一个普通的bean,然后在运行期的某个时刻就变成了动态代理bean,有可能就是BeanPostProcessor做了这方面的事情
我们查看BeanPostProcessor的实现类:
发现有一个实现类好像和我们的aop有关:AbstractAutoProxyCreator
差不多就是这个意思,判断某个bean是否需要被代理,需要被代理的就会动态代理创建出来,
其中:
/**
* 如果子类将bean标识为一个要代理的bean,则使用配置的拦截器创建一个代理。
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
/**
* 必要时包装给定的bean,如果他资格被代理。
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
最终动态代理在createProxy方法中proxyFactory.getProxy(getProxyClassLoader())执行
这里有BeanPostProcessor的一个小应用可以看看:Spring源码分析(五) – Spring中的BeanPostProcessor
其他详细的使用就不在这里介绍了
本文地址:https://blog.csdn.net/qq_39327985/article/details/107357290
如对本文有疑问, 点击进行留言回复!!
详解SpringBoot修改启动端口server.port的四种方式
网友评论