本篇文章主要内容
1.环境设计
BeanFactory 和 ApplicationContext 的关系
2.扫描注册beanDefinition
Spring优先注册配置类原则即手动指定的配置类会优先扫描加载,看代码
XxAnnotationConfigApplicationContext context = new XxAnnotationConfigApplicationContext(AppConfiguration.class);
@XxConfiguration
@XxComponentScans
public class AppConfiguration {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@XxComponent
public @interface XxConfiguration {
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface XxComponentScans {
String[] value() default "";
}
Spring 在运行 new XxAnnotationConfigApplicationContext(AppConfiguration.class)这行代码的时候 Spring 环境开始初始化 会进入下面带参数的构造方法
package com.xx.context;
/**
* @author wanganfen
* @Date 2021/7/8 9:19
*/
public class XxAnnotationConfigApplicationContext extends XxAbstractApplicationContext{
private final XxAnnotatedBeanDefinitionReader reader;
public XxAnnotationConfigApplicationContext(){
this.reader = new XxAnnotatedBeanDefinitionReader(this);
}
public XxAnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
registerConfiguration(annotatedClasses);
refresh();
}
private void registerConfiguration(Class<?>... annotatedClasses){
this.reader.register(annotatedClasses);
}
private void refresh(){
synchronized (this){
//XxDefaultListableBeanFactory beanFactory = getXxDefaultListableBeanFactory();
initBeanFactory();
invokeBeanFactoryPostProcessors();
registerBeanPostProcessors(this);
finishBeanFactoryInitialization();
}
}
}
1.this 会调用无参的构造方法和父类的无参构造方法
本类的无参构造方法初始化了一个XxAnnotatedBeanDefinitionReader reader 读取器 省略的代码在gitee里面均有。
父类
package com.xx.context;
import com.xx.component.StringUtils;
import com.xx.processors.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author wanganfen
* @Date 2021/7/8 9:45
*/
public abstract class XxAbstractApplicationContext implements XxBeanDefinitionRegistry{
private final XxDefaultListableBeanFactory beanFactory;
private final List<XxBeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
public XxAbstractApplicationContext(){
this.beanFactory = new XxDefaultListableBeanFactory();
}
//省略......
}
父类的构造方法实例化了一个 XxDefaultListableBeanFactory 工厂。初始化工厂的时候又填充了一些关于通知的属性,同时也实例化了一个对象。
package com.xx.context;
import com.xx.advisor.XxAspectJ;
import com.xx.component.GenerateBeanNameUtils;
import com.xx.component.StringUtils;
import com.xx.extend.XxFactoryBean;
import com.xx.handle.MethodAdviceHandle;
import com.xx.handle.MethodAfterAdviceHandle;
import com.xx.handle.MethodAroundAdviceHandle;
import com.xx.handle.MethodBeforeAdviceHandle;
import com.xx.processors.XxBeanPostProcessor;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author wanganfen
* @Date 2021/7/8 9:11
*/
public class XxDefaultListableBeanFactory extends XxAbstractBeanFactory{
private final Map<String,XxBeanDefinition> xxBeanDefinitionMaps = new ConcurrentHashMap<String, XxBeanDefinition>();
private final Map<String,Object> singletonObjects = new ConcurrentHashMap<String, Object>();
private final Map<Class<?>, Object> beansOfType = new ConcurrentHashMap<Class<?>,Object>();
private final List<Class<?>> scannerBeanInterfaces = new ArrayList<>();
private final List<String> beanNames = new ArrayList<>();
private final List<XxBeanPostProcessor> xxBeanPostProcessors = new ArrayList<>();
private final Map<Class<?>,List<String>> interfaceOfType = new ConcurrentHashMap<>();
private final Map<String, XxAspectJ> xxAspectJMaps = new ConcurrentHashMap<>();
private final Set<String> isSingletonCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final XxAbstractAutowireCapableBeanFactory capableBeanFactory = new XxAbstractAutowireCapableBeanFactory(this);
public XxDefaultListableBeanFactory(){
new XxAbstractAutowireCapableBeanFactory(this);
List<MethodAdviceHandle> list = new ArrayList<>();
list.add(new MethodAroundAdviceHandle());
list.add(new MethodBeforeAdviceHandle());
list.add(new MethodAfterAdviceHandle());
this.getBeansOfType().put(MethodAdviceHandle.class, list);
}
//省略......
}
回到上面的初始化读取器的方法,读取器里面有一个注册beanDefinition的方法。注册的对象就是上下文传进来的AppConfiguration
AppConfiguration 的两个注解 一个是声明为一个配置类,一个是扫描路径如果不写就默认为所有
package com.xx.context;
import com.xx.anno.XxConfiguration;
import com.xx.component.GenerateBeanNameUtils;
import com.xx.component.StringUtils;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Objects;
/**
* @author wanganfen
* @Date 2021/7/8 9:21
*/
public class XxAnnotatedBeanDefinitionReader {
private final XxBeanDefinitionRegistry registry;
public XxAnnotatedBeanDefinitionReader(XxBeanDefinitionRegistry registry){
this.registry = registry;
}
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBeanDefinition(annotatedClass);
}
}
public void registerBeanDefinition(Class<?> annotatedClass) {
Annotation[] annotations = annotatedClass.getAnnotations();
boolean b = Arrays.stream(annotations).anyMatch(x -> x.annotationType().isAnnotationPresent(XxConfiguration.class));
if (b || annotatedClass.isAnnotationPresent(XxConfiguration.class)) {
XxConfiguration xxConfiguration = annotatedClass.getAnnotation(XxConfiguration.class);
String beanName = Objects.nonNull(xxConfiguration) && StringUtils.isNotEmpty(xxConfiguration.value())? xxConfiguration.value() : GenerateBeanNameUtils.generateBeanName(annotatedClass.getSimpleName());
XxBeanDefinition beanDefinition = new XxBeanDefinition();
beanDefinition.setBeanClass(annotatedClass);
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
registerConfiguration(annotatedClasses);将AppConfiguration注册为一个beanDefinition,可以传多个
注册成一个beanDefinition的时候会往List<String> beanNames 和 Map<String,beanDefinition> map里面填充数据。后期去走bean的生命周期的时候是循环的List<String> beanNames 这个集合 而并非Map<String,beanDefinition> map ,因为要确保AppConfiguration是第一个生成SpringBean的。
注册的代码 注册成beanDefinition的时候有一个很重要的属性就是beanClass 这个beanClass ,反射时需要用到。
@Override
public void registerBeanDefinition(String beanName, XxBeanDefinition beanDefinition) {
if(StringUtils.isNotEmpty(beanName)){
this.xxBeanDefinitionMaps.put(beanName,beanDefinition);
this.beanNames.add(beanName);
}
}
最后refresh方法
private void refresh(){
synchronized (this){
//XxDefaultListableBeanFactory beanFactory = getXxDefaultListableBeanFactory();
initBeanFactory();
invokeBeanFactoryPostProcessors();
registerBeanPostProcessors(this);
finishBeanFactoryInitialization();
}
}
初始化beanFactory 上篇文章中介绍到了 beanFactoryPostProcessor的处理器,这一段代码就实例化了一个 XxConfigurationClassPostProcessor
将这个处理器放到了一个beanFactoryPostProcessor后置处理器的集合中去了。
invokeBeanFactoryPostProcessors();然后执行这个集合里面所有的beanFactoryPostProcessor XxConfigurationClassPostProcessor完成扫描工作
protected void invokeBeanFactoryPostProcessors(){
for (XxBeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessors) {
beanFactoryPostProcessor.postProcessBeanDefinitionRegistry(beanFactory);
}
List<String> beanNames = beanFactory.getBeanNames();
for (String beanName : beanNames) {
XxBeanDefinition xxBeanDefinition = beanFactory.getXxBeanDefinitionMaps().get(beanName);
if(XxBeanFactoryPostProcessor.class.isAssignableFrom(xxBeanDefinition.getBeanClass())){
XxBeanFactoryPostProcessor beanFactoryPostProcessor = (XxBeanFactoryPostProcessor)getBean(beanName);
beanFactoryPostProcessor.postProcessBeanDefinitionRegistry(beanFactory);
}
}
}
先执行 XxConfigurationClassPostProcessor这个内置的,再来执行我们自己扩展的处理器,因为第一个for循环已经完成了扫描工作,所以第二个for循环是可以拿到我们自定义的处理器的。
在spring源码中,执行beanFactoryPostProcessors 是有一定的规律的。具体的规律可以看看这篇文章Spring IOC初始化流程 里面有提到。
package com.xx.processors;
import com.xx.anno.*;
import com.xx.component.CollectionUtils;
import com.xx.component.GenerateBeanNameUtils;
import com.xx.component.StringUtils;
import com.xx.context.XxBeanDefinition;
import com.xx.context.XxBeanDefinitionRegistry;
import com.xx.context.XxClassPathBeanDefinitionScanner;
import com.xx.context.XxDefaultListableBeanFactory;
import com.xx.extend.XxImportBeanDefinitionRegistrar;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author wanganfen
* @Date 2021/7/8 10:30
*/
public class XxConfigurationClassPostProcessor implements XxBeanFactoryPostProcessor {
private List<Class<?>> classList = new ArrayList<>();
private List<Class<?>> scannerList = new ArrayList<>();
@Override
public void postProcessBeanDefinitionRegistry(XxBeanDefinitionRegistry registry) {
XxDefaultListableBeanFactory beanFactory = (XxDefaultListableBeanFactory) registry;
for (String beanName : beanFactory.getXxBeanDefinitionMaps().keySet()) {
XxBeanDefinition xxBeanDefinition = beanFactory.getBeanDefinition(beanName);
Annotation[] annotations = xxBeanDefinition.getBeanClass().getAnnotations();
boolean b = Arrays.stream(annotations).anyMatch(x -> x.annotationType().isAnnotationPresent(XxConfiguration.class));
if(b || xxBeanDefinition.getBeanClass().isAnnotationPresent(XxConfiguration.class)){
XxComponentScans xxComponentScanners = (XxComponentScans) xxBeanDefinition.getBeanClass().getAnnotation(XxComponentScans.class);
scannerList = Objects.isNull(xxComponentScanners) ?
beanFactory.loadRootResources() : beanFactory.loadResources(xxComponentScanners.value());
classList.addAll(scannerList);
}
}
if(CollectionUtils.isNotEmpty(classList)){
for (Class<?> aClass : classList) {
if(aClass.isAnnotation() || aClass.isEnum()){
continue;
}
Annotation[] annotations = aClass.getAnnotations();
boolean b = Arrays.stream(annotations).anyMatch(x -> x.annotationType().isAnnotationPresent(XxComponent.class));
if(b || aClass.isAnnotationPresent(XxComponent.class)){
XxComponent value = aClass.getAnnotation(XxComponent.class);
if(Objects.isNull(value)){
registerBeanDefinition(beanFactory,"",aClass);
}else{
registerBeanDefinition(beanFactory,value.value(),aClass);
}
handleBean(beanFactory,aClass);
}
if(aClass.isInterface()){
beanFactory.getScannerBeanInterfaces().add(aClass);
}
}
for (Class anInterface : beanFactory.getScannerBeanInterfaces()) {
beanFactory.getXxBeanDefinitionMaps().forEach((key,value)->{
if(anInterface.isAssignableFrom(value.getBeanClass())){
List<String> beanNameList = beanFactory.getInterfaceOfType().get(anInterface);
if(CollectionUtils.isEmpty(beanNameList)){
beanNameList = new ArrayList<>();
}
beanNameList.add(key);
beanFactory.getInterfaceOfType().put(anInterface,beanNameList);
}
});
}
handImport(beanFactory,registry);
}
}
private void handleBean(XxDefaultListableBeanFactory beanFactory,Class clazz){
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(XxBean.class)){
XxBean xxBean = method.getAnnotation(XxBean.class);
String xxBeanName = xxBean.value();
if(StringUtils.isEmpty(xxBeanName)){
xxBeanName = method.getName();
}
registerBeanDefinition(beanFactory,xxBeanName,method.getReturnType());
}
}
}
private void handImport(XxDefaultListableBeanFactory beanFactory,XxBeanDefinitionRegistry registry){
for (Class<?> aClass : classList) {
if(aClass.isAnnotationPresent(XxImport.class)){
XxImport xxImport = aClass.getAnnotation(XxImport.class);
Class<?>[] valueList = xxImport.value();
for (Class<?> value : valueList) {
String beanName = GenerateBeanNameUtils.generateBeanName(value.getSimpleName());
registerBeanDefinition(beanFactory,beanName,value);
if(XxImportBeanDefinitionRegistrar.class.isAssignableFrom(value)){
Object bean = beanFactory.getBean(beanName);
XxImportBeanDefinitionRegistrar beanDefinitionRegistrar = (XxImportBeanDefinitionRegistrar) bean;
beanDefinitionRegistrar.registerBeanDefinitions(registry);
beanFactory.getSingletonObjects().put(beanName,bean);
}
}
}
}
}
private void registerBeanDefinition(XxDefaultListableBeanFactory beanFactory,String name,Class clazz){
String beanName = StringUtils.isNotEmpty(name) ? name : GenerateBeanNameUtils.generateBeanName(clazz.getSimpleName());
if(!beanFactory.getXxBeanDefinitionMaps().containsKey(beanName)){
XxBeanDefinition beanDefinition = new XxBeanDefinition();
beanDefinition.setBeanClass(clazz);
beanFactory.registerBeanDefinition(beanName,beanDefinition);
}
}
}
这个扫描里面处理了一些注解 如XxConfiguration,XxComponentScans,XxComponent,XxBean,XxImport之类的,会将被这些注解修饰的JavaBean 或者方法注册成一个beanDefinition
源码中被XxConfiguration注解修饰的bean还会进行cglib增强。
Annotation[] annotations = aClass.getAnnotations();
boolean b = Arrays.stream(annotations).anyMatch(x -> x.annotationType().isAnnotationPresent(XxComponent.class));
这样一行判断的目的是 比如 XxConfiguration里面又被XxComponent修饰了。那么直接aClass.isAnnotationPresent(XxComponent.class));是获取不到的。
扫描代码
package com.xx.context;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class XxClassPathBeanDefinitionScanner {
private final ClassLoader classLoader = XxClassPathBeanDefinitionScanner.class.getClassLoader();
private final List<Class<?>> clazz = new ArrayList<>();
public List<Class<?>> loadResources(String[] value){
for (String path : value) {
String classpath = path.replace(".","/");
URL resource = classLoader.getResource(classpath);
File file = new File(resource.getFile());
this.analysisFile(file);
}
return clazz;
}
public List<Class<?>> loadRootResources(){
String path = classLoader.getResource("").getPath();
this.analysisFile(new File(path));
return clazz;
}
private void analysisFile(File file){
for (File listFile : file.listFiles()) {
if(listFile.isDirectory()){
analysisFile(listFile);
}else{
doLoadFile(listFile);
}
}
}
private void doLoadFile(File file){
String filePath = file.getAbsolutePath();
if(filePath.endsWith(".class")){
String tempFile = filePath.substring(filePath.indexOf("com"), filePath.indexOf(".class"));
tempFile = tempFile.replace("\\",".");
try {
clazz.add(classLoader.loadClass(tempFile));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
3.填充BeanPostProcessors属性
registerBeanPostProcessors(this);
protected void registerBeanPostProcessors(XxAnnotationConfigApplicationContext context){
this.beanFactory.getXxBeanPostProcessors().add(new XxHandleAdviceBeanPostProcessor(beanFactory));
this.beanFactory.getXxBeanPostProcessors().add(new XxAutowireAnnotationBeanPostProcessor(beanFactory));
this.beanFactory.getXxBeanPostProcessors().add(new XxRootAwareBeanPostProcessor(context));
this.beanFactory.getXxBeanPostProcessors().add(new XxApplicationContextAwareProcessor(context));
this.beanFactory.getXxBeanPostProcessors().add(new XxInitializingBeanPostProcessor(beanFactory));
this.beanFactory.getXxBeanPostProcessors().add(new XxAutoProxyCreatorBeanPostProcessor(beanFactory));
// XxBeanPostProcessor 未做扩展,如果需要 可参照 invokeBeanFactoryPostProcessors方法
List<Class<?>> scannerBeanInterfaces = beanFactory.getScannerBeanInterfaces();
scannerBeanInterfaces.forEach(x->{
beanFactory.getBeansOfType().put(x,beanFactory.getSingletonObjects().values().stream().filter(y -> x.isAssignableFrom(y.getClass())).collect(Collectors.toList()));
});
}
填充了一些属性
XxHandleAdviceBeanPostProcessor 处理aop的通知
XxAutowireAnnotationBeanPostProcessor 处理XxAutowire注解 推断构造方法和属性注入
XxRootAwareBeanPostProcessor 处理内置的aware接口
XxApplicationContextAwareProcessor 继续处理内置的aware接口
XxInitializingBeanPostProcessor 处理初始化方法回调
XxAutoProxyCreatorBeanPostProcessor 处理aop代理对象