java 获取当月周数 java获取周一_xml


源码介绍之前,看几个问题:

  • Bean的承载对象是什么?
  • Bean的定义如何存储的?
  • Bean工厂是如何生产bean的?
  • Bean的依赖关系由谁来解决?
  • Bean工厂和ApplicationContext的区别?

Bean的构建过程

spring.xml文件中保存了我们对Bean的描述配置,BeanFactory会读取这些配置然后生成对应的Bean。

这些配置信息最后由BeanDefinition来承载。

BeanDefinition(Bean定义)

IOC实现中,我们在xml中的描述的Bean信息最后都将保存至BeanDefinition对象中,其中xml bean与BeanDefinition是一对一的关系。

xml bean的属性配置与BeanDefinition对应关系

XML-Bean BeanDefinition class beanClassName scope SCOPE_SINGLETON、SCOPE_PROTOTYPE lazy-init AbstractBeanDefinition.lazyInit constructor-arg AbstractBeanDefinition.ConstructorArgument property AbstractBeanDefinition.propertyValues factory-method AbstractBeanDefinition.factoryMethondName destroy-method AbstractBeanDefinition.destroyMethodName init-method AbstractBeanDefinition.initMethodName autowire AbstractBeanDefinition.autowireMode id name BeanDefinition.java

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; ...}

AbstractBeanDefinition.java

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { public static final String SCOPE_DEFAULT = ""; public static final int AUTOWIRE_NO = 0; public static final int AUTOWIRE_BY_NAME = 1; public static final int AUTOWIRE_BY_TYPE = 2; public static final int AUTOWIRE_CONSTRUCTOR = 3; /** @deprecated */ @Deprecated public static final int AUTOWIRE_AUTODETECT = 4; public static final int DEPENDENCY_CHECK_NONE = 0; public static final int DEPENDENCY_CHECK_OBJECTS = 1; public static final int DEPENDENCY_CHECK_SIMPLE = 2; public static final int DEPENDENCY_CHECK_ALL = 3; public static final String INFER_METHOD = "(inferred)"; private volatile Object beanClass; private String scope; private boolean abstractFlag; private boolean lazyInit; private int autowireMode; private int dependencyCheck; private String[] dependsOn; private boolean autowireCandidate; private boolean primary; private final Map qualifiers; private boolean nonPublicAccessAllowed; private boolean lenientConstructorResolution; private String factoryBeanName; private String factoryMethodName; private ConstructorArgumentValues constructorArgumentValues; private MutablePropertyValues propertyValues; private MethodOverrides methodOverrides; private String initMethodName; private String destroyMethodName; private boolean enforceInitMethod; private boolean enforceDestroyMethod; private boolean synthetic; private int role; private String description; private Resource resource; ...}

BeanDefinitionRegistry(Bean注册器)

在上面没有看到xml bean中的id、name属性对应在bean定义中,原因是id其作为当前bean的存储key注册到BeanDefinitionRegistry注册器中。name作为别名key注册到AliasRegistry注册中心。其最后都是指向对象的BeanDefinition。

BeanDefinitionRegistry.java

public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException; void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String var1); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String var1);}

AliasRegistry.java

public interface AliasRegistry { void registerAlias(String var1, String var2); void removeAlias(String var1); boolean isAlias(String var1); String[] getAliases(String var1);}

BeanDefinitionReader(Bean定义读取)

前面知道了BeanDefinition存储了xml bean信息,而BeanDefinitionRegistry基于id和name保存bean的定义,下面是xml bean到BeanDefinition然后注册到BeanDefinitionRegistry整个过程。

分为3步:

1、BeanDefinitionReader读取spring.xml

2、读取后创建BeanDefinition

3、创建好后注册到BeanDefinitionRegister

BeanDefinitionReader.java

public interface BeanDefinitionReader { //获取注册器 BeanDefinitionRegistry getRegistry(); //获取资源装载器 ResourceLoader getResourceLoader(); //获取bean类加载器 ClassLoader getBeanClassLoader(); BeanNameGenerator getBeanNameGenerator(); //基于资源装载Bean定义并注册到注册器 int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException;  int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException; //基于资源路径装载Bean定义并注册到注册器 int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException; int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException;}

装载过程demo

package com.demo.spring;import org.springframework.beans.factory.support.BeanDefinitionReader;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.Resource;import java.util.Arrays;/** * com.demo.spring * * @author Zyy * @date 2019/2/13 11:34 */public class BeanDefinitionReaderTest { public static void main(String[] args) { //创建一个简单注册器 BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); //创建bean定义读取器 BeanDefinitionReader reader = new XmlBeanDefinitionReader(registry); //创建资源读取器 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); //获取资源 Resource resource = resourceLoader.getResource("spring.xml"); //装载类定义 reader.loadBeanDefinitions(resource); //打印构建bean名称 System.out.println(Arrays.toString(registry.getBeanDefinitionNames())); }}

运行结果

[di, driver, com.demo.spring.HelloSpring#0, com.demo.spring.LookUpTest#0, helloSpring, com.demo.spring.DI#1, com.demo.spring.DI#0, helloByName]

如果未给bean设置id则:class+#+索引,来标识id

com.demo.spring.HelloSpring#0

打印一下bean定义信息

spring.xml

打印语句:

System.out.println(registry.getBeanDefinition("di"));System.out.println(registry.getAliases("di2"));

结果信息:

Generic bean: class [com.demo.spring.DI]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=init; destroyMethodName=destroy; defined in class path resource [spring.xml][Ljava.lang.String;@73a28541

BeanFactory(bean工厂)

有了Bean的定义,则下面可以用BeanFactory来进行构建bean。

BeanFactory.java

public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; //基于id或name获取一个bean Object getBean(String name) throws BeansException; //基于bean的类别获取bean(如果出现多个该类的实例,则会报错)但是可以指定primary="true"调整优先级来解决该报错  T getBean(String name, Class requiredType) throws BeansException;   T getBean(Class requiredType) throws BeansException; //基于名词获取一个bean,并覆盖默认的构造参数 Object getBean(String name, Object... args) throws BeansException;  T getBean(Class requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //指定bean与指定class是否匹配 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class> typeToMatch) throws NoSuchBeanDefinitionException; Class> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name);}

测试demo如下:

package com.demo.spring;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.DefaultResourceLoader;/** * com.demo.spring * * @author Zyy * @date 2019/2/13 12:19 */public class BeanFactoryTest { public static void main(String[] args) { //注册中心 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //读取器 XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); //设置资源加载器 reader.setResourceLoader(new DefaultResourceLoader()); //装载构建bean的定义 reader.loadBeanDefinitions("spring.xml"); //打印 System.out.println(beanFactory.getBean("di")); System.out.println(beanFactory.getBean("di2")); }}

当getBean时,看下堆栈信息,如下

at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) - locked <0x593> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at com.demo.spring.BeanFactoryTest.main(BeanFactoryTest.java:25)

看具体调用方法

instantiateClass:142, BeanUtils (org.springframework.beans)instantiate:89, SimpleInstantiationStrategy (org.springframework.beans.factory.support)instantiateBean:1147, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)createBeanInstance:1099, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)doCreateBean:513, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)main:25, BeanFactoryTest (com.demo.spring)

逐个点进去查看

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)@Overridepublic Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false);}

AbstractBeanFactory#getBean中继续调用doGetBean,查看doGetBean,由于其中代码太多,删除检查判断,只保留核心代码

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBeanprotected  T doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //从单例缓存中获取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else {  // Check if bean definition exists in this factory. //从父类工厂中获取 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try {  // Create bean instance. //mbd -> RootBeanDefinition //判断是否单例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { ... } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { ... } } } catch (BeansException ex) { ... } } return (T) bean;}

其中

Object sharedInstance = getSingleton(beanName);org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); //如果取到的为null且判断是正在创建 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //则锁住map synchronized (this.singletonObjects) { //从正在创建的earlySingletonObjects这个map中去取 singletonObject = this.earlySingletonObjects.get(beanName); //如果还是取不到 if (singletonObject == null && allowEarlyReference) { //从工厂获取 ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); //如果获取到 if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); //获取到则放到缓存中 this.earlySingletonObjects.put(beanName, singletonObject); //从工厂中移除 this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); }

其中singletonObjects、earlySingletonObjects、singletonFactories均是一个map

private final Map singletonObjects = new ConcurrentHashMap(256);private final Map earlySingletonObjects = new HashMap(16);private final Map> singletonFactories = new HashMap>(16);

对于其中的

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstanceif (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; }

其中如果是FactoryBean,则调用getObject()来获取我们自定义的bean,例如

其中返回的不是DriverFactoryBean,而是返回Driver

public Class> getObjectType() { return Driver.class;}

总结:

1、调用BeanFactory.getBean()会触发Bean的实例化。

2、DefaultSingletonBeanRegistry中缓存了单例Bean。

3、Bean的创建于初始化是由AbstractAutowireCapableBeanFactory完成的。

另外:

IOC容器只存放单例Bean,IOC容器在初始化的时候,会将所以Bean初始化在singletonObjects这个ConcurrentHashMap中。

在获取bean的时候,首先会去singletonObjects中去取,如果scope是单例则可以获取bean,如果是多例,则取不到bean,需要从mergedBeanDefinitions这个ConcurrentHashMap中获取RootBeanDefinition,这个里面包含bean的基础信息,然后判断scope是prototype(多例),则每次都会创建一个新的实例。

对于@Autowire、@Resource等注解,在启动SpringIOC容器时,容器会装载一个AutowiredAnnotationBeanPostProcessor 后置处理器,当容易扫描到@Autowire、@Resource等注解时,就会在IOC容器中自动查找需要的Bean,并装配给该对象的属性,在使用@Autowire时,首先在容器中查询对应类型的bean,如果查询不止一个,则根据名称来查,如果名称没有则抛异常,可以将required=false来解决,如果正好查询到一个,则就将该bean装配给@Autowire指定的变量。

对于bean之间相互引用的情况,比如A依赖B,B依赖A,这种情况时,先去实例化A,然后发现依赖B,接着去实例化B,如果此时发现B依赖A,容器会获取A的一个早期引用(early reference),将这个早期引用的A注入给B,然后B实例化完了,则实例化A也就完成了。当然对于这种循环引用的代码应该规避,这种不是正常的场景。

涉及的类:

BeanDefinition

DefaultResourceLoader

XmlBeanDefinitionReader

BeanDefinitionRegistry

BeanFactory

DefaultListableBeanFactory

AutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory

SingletonBeanRegistry

DefaultSingletonBeanRegistry

整个流程:

run->getBean->BeanFactory->doGetBean->AbstructBeanFactory->getSingleton(从缓存中获取,如果是单例,为空则创建并缓存,如果是多例则直接创建)->DefaultSingleonBeanRegistry->createBean->AbstractAutowireCapableBeanFactory->createBeanInstance->newInstance->Constructor->反射实例化Bean

BeanFactory 与 ApplicationContext区别

看下结构图

ApplicationContext.java


java 获取当月周数 java获取周一_xml_02


ApplicationContext.png

从图中可以看到ApplicationContext是由BeanFactory接口派生出来的,具有BeanFactory所以功能。除此之外,还具有以下功能:

1、MessageSource,提供国际化的消息访问

2、资源访问,入url和文件

3、事件传播,实现了ApplicationListener接口的bean

4、载入多个上下文(有继承关系),使每个上下文都专注于一个特定的层次,比如应用web层

类似的

DefaultListableBeanFactory.java


java 获取当月周数 java获取周一_xml_03


封面图源网络,侵权删除)