200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 【Spring】Bean的实例化过程

【Spring】Bean的实例化过程

时间:2019-05-13 20:58:48

相关推荐

【Spring】Bean的实例化过程

创建Bean的入口:org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons。

DefaultListableBeanFactory#doCreateBean

遍历所有的BeanDefinition,开始实例化

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...// 遍历所有的BD,开始实例化for (String beanName : beanNames) {// 把父BD中的属性复制到子BD中RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);/*** 不是抽象的,是单例的,不是懒加载的才能被实例化*/if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// factoryBean的实例化if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 普通bean的实例化getBean(beanName);}}}... ...}

AbstractAutowireCapableBeanFactory#createBeanInstance

寻找合适的构造方法,并实例化。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.Class<?> beanClass = resolveBeanClass(mbd, beanName);if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// 如果factory-method属性不为空,则使用factory-method方式实例化if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {if (autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);}else {return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?// 找到构造方法Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {// 构造器注入return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.// 使用默认的构造方法实例化return instantiateBean(beanName, mbd);}

如果BeanDefinition的factory-method属性不为空,那么使用factory-method的实例化过程。

AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

使用AutowiredAnnotationBeanPostProcessor来寻找带有@Autowired注解的构造方法:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)throws BeanCreationException {// Let's check for lookup methods here...... ...// Quick check on the concurrent map first, with minimal locking.Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);if (candidateConstructors == null) {// Fully synchronized resolution now...synchronized (this.candidateConstructorsCache) {candidateConstructors = this.candidateConstructorsCache.get(beanClass);if (candidateConstructors == null) {// 找到所有的构造方法Constructor<?>[] rawCandidates;try {rawCandidates = beanClass.getDeclaredConstructors();}catch (Throwable ex) {throw new BeanCreationException(beanName,"Resolution of declared constructors on bean Class [" + beanClass.getName() +"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);}List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);Constructor<?> requiredConstructor = null;Constructor<?> defaultConstructor = null;Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);int nonSyntheticConstructors = 0;// 遍历所有的构造方法for (Constructor<?> candidate : rawCandidates) {if (!candidate.isSynthetic()) {nonSyntheticConstructors++;}else if (primaryConstructor != null) {continue;}// 找到有@Autowired注解的构造方法MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);if (ann == null) {Class<?> userClass = ClassUtils.getUserClass(beanClass);if (userClass != beanClass) {try {Constructor<?> superCtor =userClass.getDeclaredConstructor(candidate.getParameterTypes());ann = findAutowiredAnnotation(superCtor);}catch (NoSuchMethodException ex) {// Simply proceed, no equivalent superclass constructor found...}}}if (ann != null) {if (requiredConstructor != null) {// 进入这里说明存在多个带有@Autowired注解的构造方法,且required全部为truethrow new BeanCreationException(beanName,"Invalid autowire-marked constructor: " + candidate +". Found constructor with 'required' Autowired annotation already: " +requiredConstructor);}boolean required = determineRequiredStatus(ann);if (required) {if (!candidates.isEmpty()) {// 进入这里说明存在多个带有@Autowired注解的构造方法,至少有一个required为truethrow new BeanCreationException(beanName,"Invalid autowire-marked constructors: " + candidates +". Found constructor with 'required' Autowired annotation: " +candidate);}requiredConstructor = candidate;}candidates.add(candidate);}else if (candidate.getParameterCount() == 0) {defaultConstructor = candidate;}}if (!candidates.isEmpty()) {// Add default constructor to list of optional constructors, as fallback.if (requiredConstructor == null) {if (defaultConstructor != null) {candidates.add(defaultConstructor);}else if (candidates.size() == 1 && logger.isInfoEnabled()) {logger.info("Inconsistent constructor declaration on bean with name '" + beanName +"': single autowire-marked constructor flagged as optional - " +"this constructor is effectively required since there is no " +"default constructor to fall back to: " + candidates.get(0));}}candidateConstructors = candidates.toArray(new Constructor<?>[0]);}else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {// 只有一个有参的构造方法candidateConstructors = new Constructor<?>[] {rawCandidates[0]};}else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};}else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {candidateConstructors = new Constructor<?>[] {primaryConstructor};}else {candidateConstructors = new Constructor<?>[0];}this.candidateConstructorsCache.put(beanClass, candidateConstructors);}}}return (candidateConstructors.length > 0 ? candidateConstructors : null);}

这里的寻找过程大致如下:

寻找带有@Autowired注解的构造方法,如果存在多个@Autowired注解的构造方法,那么所有的required属性都必须为false,不然会报错,多个带有@Autowired注解的构造方法将会按照参数个数排序,选用参数多的构造方法如果类只有一个有参构造方法,直接选用,如果存在多个有参数构造方法,Spring无法判断使用哪个构造方法,从而使用默认构造方法,如果没有默认构造方法将会报错

factory-method的实例化过程

spring中可以使用factory-method向容器中注入实例。

使用另一个类的实例方法注入

xml中的写法:

package com.morris.spring.entity;public class UserFactory {public User newInstance() {return new User("UserFactory", 20);}}

<bean id="userFactory" class="com.morris.spring.entity.UserFactory"/><bean id="user" factory-bean="userFactory" factory-method="newInstance"/>

而使用注解@Bean注入的bean也是通过factory-method进行实例化的,例如:

package com.morris.spring.config;import com.morris.spring.entity.User;import org.springframework.context.annotation.Bean;public class UserConfig {@Beanpublic User user() {return new User("UserConfig", 23);} }

就是调用UserConfig实例的user()方法。

使用本类的静态方法实例化

package com.morris.spring.entity;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class User {private String username;private int age;public static User newInstance() {return new User("User", 22);}}

<bean id="user2" class="com.morris.spring.entity.User" factory-method="newInstance"/>

源码分析

org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod

public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {BeanWrapperImpl bw = new BeanWrapperImpl();this.beanFactory.initBeanWrapper(bw);Object factoryBean;Class<?> factoryClass;boolean isStatic;String factoryBeanName = mbd.getFactoryBeanName();if (factoryBeanName != null) {// factoryBeanName不为空说明使用的是另一个类的实例方法来创建实例if (factoryBeanName.equals(beanName)) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,"factory-bean reference points back to the same bean definition");}// 根据factoryBeanName获取另一个类的实例factoryBean = this.beanFactory.getBean(factoryBeanName);if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {throw new ImplicitlyAppearedSingletonException();}this.beanFactory.registerDependentBean(factoryBeanName, beanName);factoryClass = factoryBean.getClass();isStatic = false; // 非静态}else {// factoryBeanName为空说明使用的是本类的静态方法来创建实例// It's a static factory method on the bean class.if (!mbd.hasBeanClass()) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,"bean definition declares neither a bean class nor a factory-bean reference");}factoryBean = null;factoryClass = mbd.getBeanClass();isStatic = true; // 静态}Method factoryMethodToUse = null;ArgumentsHolder argsHolderToUse = null;Object[] argsToUse = null;if (explicitArgs != null) {argsToUse = explicitArgs;}else {Object[] argsToResolve = null;synchronized (mbd.constructorArgumentLock) {factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {// Found a cached factory method...argsToUse = mbd.resolvedConstructorArguments;if (argsToUse == null) {argsToResolve = mbd.preparedConstructorArguments;}}}if (argsToResolve != null) {argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);}}if (factoryMethodToUse == null || argsToUse == null) {// Need to determine the factory method...// Try all methods with this name to see if they match the given arguments.factoryClass = ClassUtils.getUserClass(factoryClass);List<Method> candidates = null;if (mbd.isFactoryMethodUnique) {if (factoryMethodToUse == null) {factoryMethodToUse = mbd.getResolvedFactoryMethod();}if (factoryMethodToUse != null) {candidates = Collections.singletonList(factoryMethodToUse);}}if (candidates == null) {candidates = new ArrayList<>();Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);for (Method candidate : rawCandidates) {// 找到factory-method方法if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {candidates.add(candidate);}}}if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {Method uniqueCandidate = candidates.get(0);if (uniqueCandidate.getParameterCount() == 0) {mbd.factoryMethodToIntrospect = uniqueCandidate;synchronized (mbd.constructorArgumentLock) {mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;mbd.constructorArgumentsResolved = true;mbd.resolvedConstructorArguments = EMPTY_ARGS;}// 调用factory-method方法进行实例化bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));return bw;}}... ...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。