一、简介
本文主要是通过注解的方式来实现简单的Spring,但是之前对于@Component和@Autowired注解的解析方式和Spring中还是有所区别的,本文会先了解下Spring中是如何进行注解的解析过程,然后基于此对我们的简单Spring进行改造
二、Spring注解解析过程
直接看DefaultListableBeanFactory的子类XmlBeanFactory中的构造方法
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
//调用XmlBeanDefinitionReader的loadBeanDefinitions方法
this.reader.loadBeanDefinitions(resource);
}
然后一层层往下找
XmlBeanDefinitionReader类
找到doLoadBeanDefinitions方法,然后继续跟踪registerBeanDefinitions方法,调用了DefaultBeanDefinitionDocumentReader类中的registerBeanDefinitions
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
...
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
...
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
...
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader类
registerBeanDefinitions方法中调用了doRegisterBeanDefinitions,继续跟踪doRegisterBeanDefinitions方法中parseBeanDefinitions方法,继续往下调用了BeanDefinitionParserDelegate类中的parseCustomElement方法
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}
...
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
...
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
BeanDefinitionParserDelegate类
parseCustomElement方法,调用了NamespaceHandlerSupport类的parse方法
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
NamespaceHandlerSupport类
parse方法,继续调用ComponentScanBeanDefinitionParser类的parse方法
public BeanDefinition parse(Element element, ParserContext parserContext) {
return findParserForElement(element, parserContext).parse(element, parserContext);
}
ComponentScanBeanDefinitionParser类
在该类的parse方法中做了两件很重要的事情
1.scanner.doScan(basePackages) 扫包
2.registerComponents(parserContext.getReaderContext(), beanDefinitions, element) 注册组件;
public BeanDefinition parse(Element element, ParserContext parserContext) {
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
下面我们分别来看这两个重要的方法调用
scanner.doScan(basePackages) 调用了ClassPathBeanDefinitionScanner类中的doScan方法,findCandidateComponents方法,用来解析@Compoent注解标注的类,解析出来后注册为BeanDefinition,到此@Compoent相关的注解也就解析完成了。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
registerComponents(parserContext.getReaderContext(), beanDefinitions, element)
最主要的是调用了AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source)
protected void registerComponents(
XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
Object source = readerContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
}
// Register annotation config processors, if necessary.
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) {
Set<BeanDefinitionHolder> processorDefinitions =
AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
}
}
readerContext.fireComponentRegistered(compositeDef);
}
AnnotationConfigUtils类
registerAnnotationConfigProcessors对Spring内置的BeanPostProcessor类进行注册成BeanDefinition的操作,其中包括AutowiredAnnotationBeanProcessor,看到名字想必也知道这个类是用来处理@Autowired注解相关的
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
...
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
到此为止,@Component标注的类以及@Autowired相关的BeanPostProcessor类都已经被解析为BeanDefition并且注册了,对于@Component标注类的实例化,那必然是在getBean时进行相关的实例化操作,而在看源码的过程中,一个问题困扰了我许久,那就是AutowiredAnnotationBeanProcessor这个类是什么时候实例化的,又是什么时候对@Autowired进行相应操作的,带着这两个问题,再次阅读源码。
对于第一个问题,简单记录下,在context体系中,大家肯定会知道一个方法,就是refresh,这个方法可以说是context体系中的核心方法了,而在这其中有一个registerBeanPostProcessors方法
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
PostProcessorRegistrationDelegate类
registerBeanPostProcessors方法,这个方法就是获取到BeanPostProcessor相关的
BeanDefinition并通过getBean方法实例化后调用本类中registerBeanPostProcessors方法,继而调用beanFactory.addBeanPostProcessor(postProcessor)将BeanPostProcessor的实例化对象注册用以后续调用。调用时机为AbstractAutowireCapableBeanFactory类中的populateBean方法,重点关注
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
这一行,其实是调用了包括AutowiredAnnotationBeanProcessor等内置BeanPostProcessor的postProcessPropertyValues方法。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(beanFactory, internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
三、简单Spring改造
package Factory.Impl;
import beanPostProcessor.Interface.BeanPostProcessor;
import reader.Impl.XmlBeanDefinitionReader;
import java.util.Map;
//新增类XmlBeanFactory
public class XmlBeanFactory extends DefaultListableBeanFactory{
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory() throws Exception {
this.reader.loadBeanDefinitions();
//此方法与Spring流程不一致,BeanFactory体系中没有注册BenaPostProcessor
registerBeanPostProcessors();
}
private void registerBeanPostProcessors() throws Exception {
Map<String, Object> beanPostProcessorMap = this.getBeansOfType(BeanPostProcessor.class);
for (Object bean : beanPostProcessorMap.values()) {
this.addBeanPostProcessor((BeanPostProcessor)bean);
}
}
}
新增aware,beanPostProcessor,reader,scanner相关类,代码如下
aware
package aware.Interfae;
public interface Aware {
}
package aware.Interfae;
import Factory.Interface.BeanFactory;
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws Exception;
}
beanPostProcessor
package beanPostProcessor.Interface;
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception;
Object postProcessAfterInitialization(Object bean, String beanName) throws Exception;
}
package beanPostProcessor.Interface;
import support.PropertyValues;
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws Exception;
boolean postProcessAfterInstantiation(Object bean, String beanName) throws Exception;
void postProcessPropertyValues(Object bean, String beanName) throws Exception;
default Object getEarlyBeanReference(Object bean, String beanName) {
return bean;
}
}
package beanPostProcessor.Impl;
import Factory.Interface.BeanFactory;
import Factory.Interface.ConfigurableListableBeanFactory;
import MyAnnotation.MyAutowired;
import aware.Interfae.BeanFactoryAware;
import beanPostProcessor.Interface.InstantiationAwareBeanPostProcessor;
import cn.hutool.core.bean.BeanUtil;
import support.PropertyValues;
import java.lang.reflect.Field;
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws Exception {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
@Override
public void postProcessPropertyValues(Object bean, String beanName) throws Exception, Exception {
//此段代码通过注解填充属性,和Spring真实处理有些不同
Class<?> aClass = bean.getClass();
//获取所有声明字段
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
//是否被MyAutowired注解修饰
MyAutowired annotation = declaredField.getAnnotation(MyAutowired.class);
if(annotation!=null){
Class<?> type = declaredField.getType();
//获取该对象,如果有则返回,没有则会创建,递归的跳出条件为两个对象都创建完成(解决循环依赖的代码的一部分)
Object o = beanFactory.getBean(type.getSimpleName());
//设置属性
BeanUtil.setFieldValue(bean,declaredField.getName(),o);
}
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws Exception {
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws Exception {
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
return null;
}
}
reader
package reader.Interface;
import InstantiationStrategy.Interface.BeanDefinitionRegistry;
public interface BeanDefinitionReader {
BeanDefinitionRegistry getRegistry();
void loadBeanDefinitions() throws Exception;
}
package reader.Abstract;
import InstantiationStrategy.Interface.BeanDefinitionRegistry;
import reader.Interface.BeanDefinitionReader;
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
private final BeanDefinitionRegistry registry;
public AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
this.registry = registry;
}
@Override
public BeanDefinitionRegistry getRegistry() {
return registry;
}
}
package reader.Impl;
import InstantiationStrategy.Interface.BeanDefinitionRegistry;
import reader.Abstract.AbstractBeanDefinitionReader;
import scanner.Impl.ClassPathBeanDefinitionScanner;
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
super(registry);
}
@Override
public void loadBeanDefinitions() throws Exception {
try {
doLoadBeanDefinitions();
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doLoadBeanDefinitions() throws Exception{
scanPackage();
}
private void scanPackage() throws Exception {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(getRegistry());
scanner.doScan("com");
}
}
scanner
package scanner.Impl;
import InstantiationStrategy.Interface.BeanDefinitionRegistry;
import beanPostProcessor.Impl.AutowiredAnnotationBeanPostProcessor;
import support.BeanDefinition;
import java.util.Set;
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
private BeanDefinitionRegistry registry;
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this.registry = registry;
}
public void doScan(String basePackage) throws Exception {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition beanDefinition : candidates) {
registry.registerBeanDefinition(beanDefinition.getBeanClass().getSimpleName(), beanDefinition);
}
registry.registerBeanDefinition("cn.bugstack.springframework.context.annotation.internalAutowiredAnnotationProcessor", new BeanDefinition(AutowiredAnnotationBeanPostProcessor.class));
}
}
package scanner.Impl;
import MyAnnotation.MyComponent;
import cn.hutool.core.util.ClassUtil;
import support.BeanDefinition;
import java.util.LinkedHashSet;
import java.util.Set;
public class ClassPathScanningCandidateComponentProvider {
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(basePackage, MyComponent.class);
for (Class<?> clazz : classes) {
candidates.add(new BeanDefinition(clazz));
}
return candidates;
}
}
修改了BeanFactory相关类的代码
package Factory.Interface;
import java.util.Map;
/**
*扩展BeanFactory使其支持迭代Ioc容器持有的Bean对象 (先不关注)
*/
public interface ListableBeanFactory extends BeanFactory{
Map<String, Object> getBeansOfType(Class type) throws Exception;
}
package Factory.Interface;
import Register.Interface.SingletonBeanRegistry;
import beanPostProcessor.Interface.BeanPostProcessor;
/**
* 继承HierarchicalBeanFactory的同时继承了 注册单例Bean的SingletonBeanRegistry
*/
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
package Factory.Impl;
import Factory.Abstract.AbstractAutowireCapableBeanFactory;
import Factory.Interface.ConfigurableListableBeanFactory;
import InstantiationStrategy.Interface.BeanDefinitionRegistry;
import MyAnnotation.MyComponent;
import cn.hutool.core.util.ClassUtil;
import support.BeanDefinition;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* BeanFactory的最终实现类
*/
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
/**
* getBeanDefinition 获取BeanDefinition
* @param beanName
* @return
* @throws Exception
*/
@Override
public BeanDefinition getBeanDefinition(String beanName) throws Exception {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
throw new Exception(beanName);
}
return bd;
}
/**
* registerBeanDefinition 注册BeanDefinition
* @param beanName
* @param beanDefinition
* @throws Exception
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception {
this.beanDefinitionMap.put(beanName,beanDefinition);
}
@Override
public Map<String, Object> getBeansOfType(Class type) throws Exception {
Map<String, Object> result = new HashMap<>();
beanDefinitionMap.forEach((beanName, beanDefinition) -> {
Class beanClass = beanDefinition.getBeanClass();
if (type.isAssignableFrom(beanClass)) {
try {
result.put(beanName, getBean(beanName));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return result;
}
}
package Factory.Abstract;
import Factory.Interface.ConfigurableBeanFactory;
import Register.Abstract.FactoryBeanRegistrySupport;
import beanPostProcessor.Interface.BeanPostProcessor;
import support.BeanDefinition;
import java.util.ArrayList;
import java.util.List;
/**
* 继承FactoryBeanRegistrySupport,实现ConfigurableBeanFactory
*/
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
@Override
public Object getBean(String beanName) throws Exception {
//调用doGetBean
return doGetBean(beanName);
}
protected Object doGetBean(String beanName) throws Exception {
//获取Bean,获取到直接返回,获取不到调用createBean抽象方法,实际会调用到子类AbstractAutowireCapableBeanFactory中createBean
Object singleton = getSingleton(beanName);
if(singleton!=null){
return singleton;
}
return createBean(beanName);
}
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
protected abstract Object createBean(String beanName) throws Exception;
protected abstract BeanDefinition getBeanDefinition(String beanName) throws Exception;
}
package Factory.Abstract;
import Factory.Interface.AutowireCapableBeanFactory;
import InstantiationStrategy.Impl.SimpleInstantiationStrategy;
import InstantiationStrategy.Interface.InstantiationStrategy;
import MyAnnotation.MyAutowired;
import aware.Interfae.BeanFactoryAware;
import beanPostProcessor.Interface.BeanPostProcessor;
import beanPostProcessor.Interface.InstantiationAwareBeanPostProcessor;
import cn.hutool.core.bean.BeanUtil;
import support.BeanDefinition;
import support.PropertyValues;
import java.lang.reflect.Field;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();
//createBean方法
@Override
protected Object createBean(String beanName) throws Exception {
//调用doCreateBean
Object beanInstance = doCreateBean(beanName);
return beanInstance;
}
protected Object doCreateBean(String beanName) throws Exception{
//调用createBeanInstance
Object beanInstance = createBeanInstance(beanName);
//注册Bean
registerSingleton(beanName,beanInstance);
//填充Bean属性
populateBean(beanName,beanInstance);
return beanInstance;
}
protected Object createBeanInstance(String beanName) throws Exception{
//实例化Bean
return instantiateBean(beanName);
}
protected Object instantiateBean(String beanName) throws Exception {
//调用getBeanDefinition抽象方法,实际调用子类DefaultListableBeanFactory的getBeanDefinition
BeanDefinition beanDefinition = getBeanDefinition(beanName);
//获取实例化策略创建对象
return getInstantiationStrategy().instantiate(beanName,beanDefinition);
}
protected void populateBean(String beanName ,Object bean) throws Exception {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof BeanFactoryAware) {
((BeanFactoryAware) bp).setBeanFactory(this);
}
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
ibp.postProcessPropertyValues(bean,beanName);
}
}
}
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
}
四、测试
package com;
import Factory.Impl.DefaultListableBeanFactory;
import Factory.Impl.XmlBeanFactory;
import org.junit.Test;
public class test {
@Test
public void test() throws Exception {
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory();
Object userService = xmlBeanFactory.getBean("UserService");
System.out.println("");
}
}
本文主要针对Spring中是如何解析注解进行相关的学习和改造。
总结来说:在解析XML文件为BeanDefintion的时候,会做两件事情,扫包获得@Component注解标准的BeanDefintion,同时将内置的BeanPostProcessor同样注册为BeanDefintion,然后对BeanPostProcessor进行实例化注册,在创建@Componen标注对象时,从缓存中拿出BeanPostProcessor,调用其相关方法完成@Autowired对象的注入,整个过程围绕着基础的BeanDefintion和BeanFactory进行了一个很有意思的构建,大家可以跟着debug,还是挺有收获的。
本人水平有限,如有错漏,欢迎指正。
本文用作学习记录分享,如有违规请联系作者删除!