欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring源码学习08

程序员文章站 2022-05-20 09:37:55
...

1.bean的生命周期

Spring源码学习08

2.方法Object.Class.cast(Object obj)的使用

protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
		return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
	}

3.DefaultBeanDefinitonDocumentReader.doRegisterBeanDefinitions方法中在解析xml之前扩展点

protected void doRegisterBeanDefinitions(Element root) {
		//任何嵌套的<beans>元素都将导致此方法中的递归.
		//为了正确传播和保留<beans> default- *属性,
		// 跟踪当前(父)委托,可以为null, 创建新的(子)委托,引用父项以进行回退,
		//然后最终将this.delegate重置为其原始(父)引用.
		// 此行为模拟了一堆代理,而实际上并不需要一个代理。
		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;
				}
			}
		}
		//TODO 解析xml前扩展
		preProcessXml(root);
		parseBeanDefinitions(root, this.delegate);
		//TODO 解析xml后扩展
		postProcessXml(root);

		this.delegate = parent;
	}

如何扩展:

编写DefaultBeanDefinitionDocumentReaderExtend类继承自DefaultBeanDefinitionDocumentReader

/**
 * @author 周宁
 * @Date 2019-07-04 17:25
 */
public class DefaultBeanDefinitionDocumentReaderExtend extends DefaultBeanDefinitionDocumentReader {
    @Override
    protected void preProcessXml(Element root) {
        System.out.println("我开始解析xml了");
    }

    @Override
    protected void postProcessXml(Element root) {
        System.out.println("我结束解析xml");
    }
}

定义MyXmlBeanFactory继承自DefaultListableBeanFactory

public class MyXmlBeanFactory extends DefaultListableBeanFactory {

    private final XmlBeanDefinitionReader reader;

    {
        reader = new XmlBeanDefinitionReader(this);
        reader.setDocumentReaderClass(DefaultBeanDefinitionDocumentReaderExtend.class);
    }

    public MyXmlBeanFactory(Resource resource) {
        super(null);
        reader.loadBeanDefinitions(resource);
    }

使用

@Test
    public void testMyXmlBeanFactory(){
        BeanFactory beanFactory =new MyXmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
        TestBean myTestBean = (TestBean) beanFactory.getBean("testBean");
        System.out.println(myTestBean.getTestStr());
    }

场景:在某些业务中可能需要对*.xml内容做修改、验证使用

4.在解析xml每个element过程中,每解析完成一个bean/import/alias/标签Spring给我们预留了监听器接口,这里以bean举例

/**
	 * 处理给定的bean元素,解析bean定义
	 *   并在注册表中注册。
	 */
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//BeanDefinitionParserDelegate.parseBeanDefinitionElement对元素进行解析
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		//判断该标签下是否还有自定义 比如您自己定义的<mybean>元素,有还需要进行解析
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				//注册bdHolder
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// TODO 扩展点,用于对bean注册完成的监听
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

扩展

编写MyEventListener实现ReaderEventListener

/**
 * @author 周宁
 * @Date 2019-07-15 19:21
 */
public class MyEventListener implements ReaderEventListener {
    @Override
    public void defaultsRegistered(DefaultsDefinition defaultsDefinition) {

    }

    @Override
    public void componentRegistered(ComponentDefinition componentDefinition) {
        System.out.println(componentDefinition);
    }

    @Override
    public void aliasRegistered(AliasDefinition aliasDefinition) {

    }

    @Override
    public void importProcessed(ImportDefinition importDefinition) {

    }
}

编写MyXmlBeanFactory继承自DefaultListableBeanFactory

public class MyXmlBeanFactory extends DefaultListableBeanFactory {

    private final XmlBeanDefinitionReader reader;

    {
        reader = new XmlBeanDefinitionReader(this);
        reader.setEventListener(new MyEventListener());
    }

    public MyXmlBeanFactory(Resource resource) {
        super(null);
        reader.loadBeanDefinitions(resource);
    }
}

5.使用FactoryBean创建出来的对象会尽量应用BeanPostProcessor的postProcessAfterInitialization方法,对对象进行后置处理

6.AbstractAutowireCapableBeanFactory.createBean方法中,在真正创建bean(doCreateBean方法)被调用之前,提供了返回代理bean的方法,通过该扩展点,可以实现代理

/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * 该类的中心方法:创建bean实例,填充bean实例,应用后处理器等
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		//确保此时实际解析了bean类,并且
		//在动态解析的Class的情况下克隆bean定义
		//它不能存储在共享的merged bean定义中
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			//验证bean元素配置的lookup-method和replace-method方法是否存在
			//并且标记lookup-method和replace-method的那些方法重载了吗
			//如果方法未被重载,那么是不是就不需要通过参数去匹配相应的方法了节省了效率
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			//为InstantiationAwareBeanPostProcessor提供返回代理而不是目标bean实例的机会
			//TODO 扩展点 实现AOP的关键
			//在实例化之前解析,如果不为null则直接返回
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
		//真正创建bean的方法
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		//在实例化前解析为true,标识需要提前解析,一般情况下beforeInstantiationResolved是为false
		//所以不会走这段逻辑的
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				//目标bean的类型
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法调用
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						//BeanPostProcessor的postProcessAfterInitialization被执行
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

使用

定义需要代理的bean

/**
 * @author 周宁
 * @Date 2019-07-15 21:07
 */
public class ProBean {

    public ProBean() {
    }

    public void doSomething(){
        System.out.println("处理中");
    }
}

编写MyMethodInterceptor实现接口MethodInterceptor

public class MyMethodInterceptor implements MethodInterceptor {


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("目标方法前:" + method+"\n");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("目标方法后:" + method+"\n");
        return object;
    }
}

编写MyInstantiationAwareBeanPostProcessor实现InstantiationAwareBeanPostProcessor接口

/**
 * @author 周宁
 * @Date 2019-07-15 21:10
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass==ProBean.class){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanClass);
            enhancer.setCallback(new MyMethodInterceptor());
            ProBean proxyBean = (ProBean)enhancer.create();
            return proxyBean;
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return false;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

编写测试类

@Test
    public void testInstantiationAwareBeanPostProcessor(){
        BeanFactory beanFactory =new MyXmlBeanFactory(new ClassPathResource("instantiationAwareBeanPostPorcessorTest.xml"));
        ((MyXmlBeanFactory) beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());

        ProBean proxyBean = (ProBean) beanFactory.getBean("proBean");
        proxyBean.doSomething();
    }

运行测试程序可以看到方法被代理了

目标方法前:public void org.springframework.study.day07.ProBean.doSomething()

处理中
目标方法后:public void org.springframework.study.day07.ProBean.doSomething()

7.bean的实例化AbstractAutowireCapableBeanFactory.createBeanInstance方法根据bean定义实例化的方式:如通过工厂方法创建bean、通过构造函数创建bean定义、通过objectFactory创建,在实例化部分有如下代码

/**
	 * Instantiate the given bean using its default constructor.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return a BeanWrapper for the new instance
	 */
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

其中可以看到有getInstantiationStrategy(),Spring针对bean是否需要生成代理,分别实现了两种策略类CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy。

8.bean实例化后Spring给我们一次修改MergedBeanDefinition的机会

//允许后处理器修改MergedBeanDefinition
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//TODO 扩展点
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}
/**
	 * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
	 * invoking their {@code postProcessMergedBeanDefinition} methods.
	 * 将MergedBeanDefinitionPostProcessors应用于指定的bean定义,
	 * *调用他们的{@code postProcessMergedBeanDefinition}方法。
	 * @param mbd the merged bean definition for the bean
	 * @param beanType the actual type of the managed bean instance
	 * @param beanName the name of the bean
	 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
	 */
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

9.在存在循环引用、允许循环引用Spring通过暴露ObjectFactory解决循环引用,Spring给了我们一个入口可以处理为了解决循环引用暴露的对象

/**
	 * Obtain a reference for early access to the specified bean,
	 * typically for the purpose of resolving a circular reference.
	 *
	 * 获取早期访问指定bean的引用,通常用于解析循环引用
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @param bean the raw bean instance
	 * @return the object to expose as bean reference
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					//使用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference对暴露的bean进行
					//处理或者直接返回原bean,通常返回与原bean相同的引用
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
					if (exposedObject == null) {
						return null;
					}
				}
			}
		}
		return exposedObject;
	}

看起来像是给内部使用的,俺也不知道怎么用Q A Q

10.使用PropertyEditor,转换给定属性;

a.用户转换给定bean

定义User.java

/**
 * @author 周宁
 * @Date 2019-07-16 9:45
 */
public class User {

    private Integer id;

    private String name;

    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", address=" + address + "]";
    }
}

定义UserHolder.java

/**
 * @author 周宁
 * @Date 2019-07-16 9:52
 */
public class UserHolder {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

定义UserPropertyEditor继承自PropertyEditorSupport

/**
 * @author 周宁
 * @Date 2019-07-16 9:47
 */
public class UserPropertyEditor extends PropertyEditorSupport {
    @Override
    public String getAsText() {
        User user = (User) getValue();
        return user.toString();
    }
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        String[] fields = text.split(",");
        if (fields.length != 3) {
            throw new IllegalArgumentException("User 属性配置错误");
        }
        User user = new User();
        try {
            int id = Integer.parseInt(fields[0]);
            user.setId(id);
        } catch (Exception e) {
            throw new IllegalArgumentException("User的属性配置错误");
        }
        user.setName(fields[1]);
        user.setAddress(fields[2]);
        setValue(user);
    }
}

执行测试类

@Test
    public void testPropertyEditor(){
        BeanFactory beanFactory =new MyXmlBeanFactory(new ClassPathResource("propertyEditorTest.xml"));
        ((MyXmlBeanFactory) beanFactory).registerCustomEditor(User.class,UserPropertyEditor.class);
        UserHolder userHolder = (UserHolder) beanFactory.getBean("userHolder");
        System.out.println(userHolder.getUser().toString());
    }

b.用于解析给定字符串

@Test
    public void testSpringPropertyEditor(){
        PropertiesEditor propertiesEditor = new PropertiesEditor();
        propertiesEditor.setAsText("username=zhouning\r\npassword=11111111111");
        Properties p = (Properties) propertiesEditor.getValue();
        for(Map.Entry<Object,Object> e : p.entrySet()){
            System.out.println("key:"+e.getKey());
            System.out.println("value:"+e.getValue());
        }
    }

11.在给bean实例进行赋值,自动装配操作之前。给了我们一次为任何InstantiationAwareBeanPostProcessors提供在设置属性之前修改bean状态的机会,我们可以通过该扩展点方法跳出装配bean操作

/**
	 * Populate the bean instance in the given BeanWrapper with the property values
	 * from the bean definition.
	 *
	 * 使用bean定义中的属性值来操作给定BeanWrapper中的bean实例
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param bw the BeanWrapper with bean instance
	 */
	protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
		//获取支持Map的propertyValue,从xml中解析到property value配置
		PropertyValues pvs = mbd.getPropertyValues();
		//bean实例为null
		if (bw == null) {
			//属性不为空,但是没有创建bean直接抛出异常
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				//跳过属性填充步骤
				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.
		//为任何InstantiationAwareBeanPostProcessors提供在设置属性之前修改bean状态的机会
		//可以用来支持属性注入的类型
		boolean continueWithPropertyPopulation = true;
		//
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//TODO 是否执行post-processor,如果返回false代表需要对bean进行属性装配,反之退出bean装配
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		//如果不填充bean则终止bean的填充
		if (!continueWithPropertyPopulation) {
			return;
		}
		//
		//
		//下面的逻辑会把构造器中需要依赖注入的bean或者需要@Autowired注解或者xml配置autowire为byName或者byType
		// 修饰的bean放到propertyValue中,如果bean依赖的bean还未创建
		//则会在autowireByName或者autowireByType中创建

		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// 根据名称自动注入逻辑,如果某些依赖的bean没有创建则在这里会被初始化
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// 根据类型自动注入.如果某些依赖的bean没有创建,则在这里会被初始化
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//是否有InstantiationAwareBeanPostProcessor处理器
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//是否需要依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
		//如果有InstantiationAwareBeanPostProcessor处理器或者需要依赖检查
		if (hasInstAwareBpps || needsDepCheck) {
			//需要进行依赖检查的propertyrDescriptor
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//TODO 扩展点 所有需要进行依赖检查的属性进行后处理
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				//depends-on属性检查
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//属性应用到bean
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

12.在bean属性自动装配之后,属性赋值之前,让我们对bean的propertyValue进行后置处理的操作,我们可以通过implements InstantiationAwareBeanPostProcessor的postProcessPropertyValue方法做一些应用

if (hasInstAwareBpps || needsDepCheck) {
			//需要进行依赖检查的propertyrDescriptor
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//TODO 扩展点 所有需要进行依赖检查的属性进行后处理
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				//depends-on属性检查
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

 

相关标签: Spring源码