我是靠谱客的博主 单纯鼠标,最近开发中收集的这篇文章主要介绍spring 后置处理器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

spring 中的注解,比如@Autowired 、dubbo的@AutowiredDubbo,还有@Value等等的使用,是如何完成依赖注入的?

在spring中,有提供一类特殊的接口,叫做后置处理器

 这类接口提供给处理类,可以修改bean的值,或者在bean实例化过程中添加其他处理:

 

public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

 接下来分析一下后置处理器的使用。

 apollo在项目中的使用:

@SpringBootApplication
@ComponentScan(basePackages = (MobileOfficeApplication.keKeingPackages))
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@EnableJpaAuditing
@EnableApolloConfig
@EnableDubbo
@EnableAsync
@EntityScan({MobileOfficeApplication.keKeingPackages})
@EnableFeignClients(basePackages = (MobileOfficeApplication.keKeingPackages))
public class MobileOfficeApplication {
static final String keKeingPackages = "cn.*.*";
public static void main(String[] args) {
SpringApplication.run(MobileOfficeApplication.class, args);
}
}

 

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({ApolloConfigRegistrar.class})
public @interface EnableApolloConfig {
String[] value() default {"application"};
int order() default 2147483647;
}

 看这里的注解@Import({ApolloConfigRegistrar.class}),import注解用于引入bean,ApolloConfigRegistrar对象是apollo包下的。

public class ApolloConfigRegistrar implements ImportBeanDefinitionRegistrar {
public ApolloConfigRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName()));
String[] namespaces = attributes.getStringArray("value");
int order = (Integer)attributes.getNumber("order");
PropertySourcesProcessor.addNamespaces(Lists.newArrayList(namespaces), order);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(), PropertySourcesPlaceholderConfigurer.class);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesProcessor.class.getName(), PropertySourcesProcessor.class);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(), ApolloAnnotationProcessor.class);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueDefinitionProcessor.class.getName(), SpringValueDefinitionProcessor.class);
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(), ApolloJsonValueProcessor.class);
}
}

 registerBeanDefinitions方法中会注册多个对象,这些对象是用来做什么的呢?

public class SpringValueProcessor extends ApolloProcessor implements BeanFactoryPostProcessor 

 查看apollo源码

public abstract class ApolloProcessor implements BeanPostProcessor, PriorityOrdered {
public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered
public class ApolloJsonValueProcessor extends ApolloProcessor implements BeanFactoryAware
public class SpringValueDefinitionProcessor implements BeanDefinitionRegistryPostProcessor
public class SpringValueProcessor extends ApolloProcessor implements BeanFactoryPostProcessor
public class ApolloAnnotationProcessor extends ApolloProcessor
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware

 apollo注册的bean对象,都有继承或者实现spring提供的接口。

 BeanFactoryPostProcessor和BeanPostProcessor这两个接口都是初始化bean时对外暴露的入口之一,BeanFactoryPostProcessor是bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。

apollo功能最重要的一点就是动态的修改对象属性,那看到这里应该都会猜想功能的实现是跟BeanFactoryPostProcessor这个接口有关。

processField方法有处理Value注解,具体apollo的逻辑以后再细心研读分享一下。

protected void processField(Object bean, String beanName, Field field) {
Value value = (Value)field.getAnnotation(Value.class);
if (value != null) {
Set<String> keys = this.placeholderHelper.extractPlaceholderKeys(value.value());
if (!keys.isEmpty()) {
Iterator var6 = keys.iterator();
while(var6.hasNext()) {
String key = (String)var6.next();
SpringValue springValue = new SpringValue(key, value.value(), bean, beanName, field, false);
this.springValueRegistry.register(key, springValue);
logger.debug("Monitoring {}", springValue);
}
}
}
}

AutowiredDubbo处理相关代码: 

@Configuration
@ConditionalOnBean(
annotation = {EnableDubbo.class}
)
@EnableConfigurationProperties({DubboConfiguration.class})
public class ConsumerAutoConfiguration implements BeanPostProcessor {
private Logger logger = LoggerFactory.getLogger(ConsumerAutoConfiguration.class);
private Map<String, Object> refrences = new ConcurrentHashMap();
@Autowired
private ApplicationContext applicationContext;
@Autowired
private DubboConfiguration configuration;
public ConsumerAutoConfiguration() {
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Object current = bean;
Class<?> clazz = bean.getClass();
if (AopUtils.isAopProxy(bean)) {
clazz = AopUtils.getTargetClass(bean);
}
try {
if (AopUtils.isCglibProxy(bean)) {
current = getCglibProxyTargetObject(bean);
} else if (AopUtils.isJdkDynamicProxy(bean)) {
current = getJdkDynamicProxyTargetObject(bean);
}
} catch (Exception var21) {
this.logger.error("", var21);
}
try {
Field[] var5 = clazz.getDeclaredFields();
int var6 = var5.length;
for(int var7 = 0; var7 < var6; ++var7) {
Field field = var5[var7];
AutowiredDubbo autowiredDubbo = (AutowiredDubbo)field.getAnnotation(AutowiredDubbo.class);
if (autowiredDubbo != null) {
Class<?> type = field.getType();
ReferenceBean<?> dubboConsumer = this.initAutowiredDubboBean(type, autowiredDubbo);
String group = dubboConsumer.getGroup();
String version = dubboConsumer.getVersion();
String key = type + "_" + group + "_" + version;

 

那么后置处理又是如何生效的?

 在spring boot启动阶段,

 public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}

 这里的方法就是调用所有BeanFactoryPostProcessor的postProcessBeanFactory方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

 

 private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
postProcessor.postProcessBeanFactory(beanFactory);
}
}

上面介绍的是 BeanFactoryPostProcessor 接口的调用过程。

BeanPostProcessor 的实现原理跟踪:

 


if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

继续跟踪到createBean—>doCreateBean—>initializeBean

这里看到applyBeanPostProcessorsBeforeInitialization 和applyBeanPostProcessorsAfterInitialization方法 

 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
return null;
}
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

 执行前置处理

 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator();
do {
if (!var4.hasNext()) {
return result;
}
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
} while(result != null);
return result;
}

 执行后置处理

 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator();
do {
if (!var4.hasNext()) {
return result;
}
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessAfterInitialization(result, beanName);
} while(result != null);
return result;
}

我们就找到了BeanPostProcessor 的处理过程了。

最后

以上就是单纯鼠标为你收集整理的spring 后置处理器的全部内容,希望文章能够帮你解决spring 后置处理器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部