之前我们学习了java的自定义注解,而且我们可以非常方便的进行注解值到实体真实值得转变。那么我们如何将这些标记值设置到spring容器中?那么我们就需要了解一些spring的知识。我们知道spring提供了很多扩展的接口。这其中有一个BeanPostProcessor的接口。
话不多说,直接上代码
public class MyBeanPostProcessor implements BeanPostProcessor {
//在bean实例化之后调用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
//在bean实例化之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
try {
parseAnnotation(bean);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return bean;
}
//在bean实例化之后进行参数赋值,处理完毕之后,spring容器中的bean就是注解中的值了。
public void parseAnnotation(Object bean) throws IllegalAccessException {
//获取公有和私有的属性
Field[] fields = bean.getClass().getDeclaredFields();
for (int i=0;i<fields.length;i++){
//抑制对private的检测
fields[i].setAccessible(true);
Object value=fields[i].get(bean);
MyField myField=fields[i].getAnnotation(MyField.class);
//如果默认传入的是空的
if (null!=myField&& StringUtils.isEmpty(value)){
fields[i].set(bean,myField.myName());
}
}
}
}
@SpringBootApplication
public class tet implements ApplicationContextAware {
@Bean(initMethod = "initSon")
public Son son(){
return new Son();
}
//不能采用其他注解修饰拥有BeanPostProcessor接口,只能用@Bean。
@Bean
public MyBeanPostProcessor getMybean(){
return new MyBeanPostProcessor();
}
private static Son son;
private static ApplicationContext context;
public static void main(String[] args) {
SpringApplication.run(tet.class, args);
son= context.getBean(Son.class);
System.out.println("新的:"+son.toString());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context=applicationContext;
}
}
我们看到我们已经拿到注解的值并修改了spring容器中bean的值了。同样的道理,我们也可以通过bean来遍历方法,然后拿到方法上的注解属性。但是使用方法上的注解的时候都是AOP来兼容代码。也就是说在切面里接受注解上边的属性。这个咋后期再研讨。现在咋没爬一爬代码,看看刚才的BeanPostProcessor是如何调用的。
首先我们看到BeanPostProcessor的两个接口。前置和后置的处理器。通过上边的例子,我们知道如果我们什么多不做,那么return bean就应该注册到Spring的容器中了。
public interface BeanPostProcessor {
//在bean实例化之后调用
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//在bean实例化之后调用
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
通过代码跟踪,在initalizeBean中
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//执行aware接口
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//aware接口
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//beanPostProcessors的前置接口
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//intit接口
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()) {
//beanPostProcessors的前置接口
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
可以看出方法执行的顺序为
invokeAwareMethods->
applyBeanPostProcessorsBeforeInitialization->
invokeInitMethods->
applyBeanPostProcessorsAfterInitialization
调用的aware接口方法
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
调用的BeanPostProcessors接口方法
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
调用的InitializingBean接口方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
所以接口的执行顺序为aware->beanpostprocess->InitializingBean->beanpostprocess
而我们的getBeanPostProcessors()就是用来获取所有实现了beanpostprocessors接口的类。那么这些类是如何放到beanfactory里的呐?
我们返爬一下代码,在beanfactory中。发现
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
{
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
我们继续向调用者跟踪,发现了核心代码。就这这个registerBeanPostProcessors方法中。
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//通过beanfactory获取实现了beanPostProcessor接口的类的名称。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//实现了beanPostProcessor接口的类数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//做了
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//具有优先级的
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//实现ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
//一般的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//优先级接口
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//如实现Orderd接口
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注册优先级的beanpostprocessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
//进行实例化
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册ordered的beanpostprocessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//一般的beanpostprocessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册一般的beanpostprocessors
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//排序
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
这里的getbean就是spring的实例化bean的过程。也就是registerBeanPostProcessors方法之后,实现BeanPostProcessors接口的类都已经实例化好了。
我们再向前走一步。
而其中的onRefresh方法是spring留给子类进行bean的初始化的。而且该方法也添加了synchronized锁,而beanPostProcessors类在其他bean初始化之前已经初始化了。所以根据上边的解释。bean初始化结束之后肯定会调用postProcessAfterInitialization,而不存在beanPostProcessors类还没有初始化的问题,就被其他类调用的问题。