instanceWrapper = createBeanInstance(beanName, mbd, args);

AbstractAutowireCapableBeanFactory.createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.确保实际已经解析了beanClass,如果是表达式,会进行表达式的运算得到className
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());
} //如果存在工厂方法,那么说明需要通过静态工厂的方式获取bean
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);
}
} // Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
} // No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
} AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, Object[] explicitArgs) { return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
} ConstructorResolver.instantiateUsingFactoryMethod public BeanWrapper instantiateUsingFactoryMethod(
final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl();
//初始化这个bean包装器,内部给这个包装器设置了类型转化器和自定的转化器
this.beanFactory.initBeanWrapper(bw); Object factoryBean;
Class<?> factoryClass;
boolean isStatic; String factoryBeanName = mbd.getFactoryBeanName();
//如果存在factoryBeanName 比如<bean id="helloWorld" factory-bean="helloWorld" factory-method="getSayHi"></bean>
if (factoryBeanName != null) {
//如果工厂bean的名字和自己相同,那么直接抛错
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
//使用getBean获取到依赖的那个工厂bean
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (factoryBean == null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
}
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared " +
"through the creation of the factory bean that its bean definition points to");
}
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
// 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;
//如果缓存中没有,那么就从准备的(也就是解析配置文件时,BeanDefinition存储的参数)构造参数中获取,这个时候的参数还是原始(配置文件中)的,没有进行类型转换的参数
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.
//判断是否被cglib代理过的,如果代理过,那么就返回其父类
factoryClass = ClassUtils.getUserClass(factoryClass);
//获取这个类定义的所有方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
List<Method> candidateSet = new ArrayList<Method>();
for (Method candidate : rawCandidates) {
//获取工厂方法
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidateSet.add(candidate);
}
}
Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
//给重载的方法排序,public修饰和参数长的排在前面
AutowireUtils.sortFactoryMethods(candidates); ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null; int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
//如果用户没有传递参数进来,那么我们需要获取配置的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//解析构造参数,通过BeanDefinitionValueResolver进行解析,解析好后放置到resolvedValues中,这里主要是将beanref的解析好和以下表达式什么的,没有进行参数类型的转换。
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} List<Exception> causes = null; for (int i = 0; i < candidates.length; i++) {
Method candidate = candidates[i];
//获取当前方法的参数类型
Class<?>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder; if (resolvedValues != null) {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {
//获取这些方法的参数名
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
//由于实际方法的参数和配置的参数之间存在位置,类型需要转化的问题,所以需要尝试换成符合对应方法的参数
argsHolder = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace("Ignoring factory method [" + candidate +
"] of bean '" + beanName + "': " + ex);
}
if (i == candidates.length - 1 && argsHolderToUse == null) {
if (causes != null) {
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
}
throw ex;
}
else {
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<Exception>();
}
causes.add(ex);
continue;
}
}
} else {
//如果配置里面没有参数,那么就使用用户设置的参数
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
} int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<Method>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
} if (factoryMethodToUse == null) {
List<String> argTypes = new ArrayList<String>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else {
Set<ValueHolder> valueHolders = new LinkedHashSet<ValueHolder>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
} if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
} try {
Object beanInstance; if (System.getSecurityManager() != null) {
final Object fb = factoryBean;
final Method factoryMethod = factoryMethodToUse;
final Object[] args = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, fb, factoryMethod, args);
}
}, beanFactory.getAccessControlContext());
}
else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
} if (beanInstance == null) {
return null;
}
bw.setWrappedInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via factory method failed", ex);
}
} ConstructorResolver.resolvePreparedArguments private Object[] resolvePreparedArguments(
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
//获取构造方法或者工厂方法的参数类型
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
//获取自定义的类型转化器,如果没有就是用bean包装器·,这个包装器在上面已经注册了默认的转化器和自定的转化器。
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);、
//构建BeanDefinition值的解析器,用于转化value
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
Object[] resolvedArgs = new Object[argsToResolve.length];
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
//获取当前下标参数值
Object argValue = argsToResolve[argIndex];
//包装成方法参数对象,持有对应的方法,参数的位置
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, argIndex);
//解析这个方法所在的类,参数的类型
GenericTypeResolver.resolveParameterType(methodParam, methodOrCtor.getDeclaringClass());
//参数是AutowiredArgumentMarker只只是个标记类,标记为自动装配的参数,这里会解析@Value注解的参数,还有会根据字段的类型去包装成某些延迟获取数据的对象,比如DependencyObjectFactory(依赖工厂bean,这种类型字段可以通过getObject获取数据),这里是方法参数的获取所以不用去管field的。最后内部会通过DefaultListableBeanFactory.doResolveDependency方法根据参数类型去获取bean
if (argValue instanceof AutowiredArgumentMarker) {
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
}
//这种类型数据一般是在解析xml配置的时候生成的,比如xml中的ref指定的bean会包装成RuntimeBeanReference,当spring看到这种类型的时候就知道,我要去BeanFactory中寻找叫这个名字的bean
else if (argValue instanceof BeanMetadataElement) {
//使用上面new出来的BeanDefinitionValueResolver进行解析
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
}
//如果只是普通的字符串,那么经过表达式解析器之后直接返回
else if (argValue instanceof String) {
argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
}
Class<?> paramType = paramTypes[argIndex];
try {
//将得到的数据进行类型转换
resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, argIndex, paramType,
"Could not convert " + methodType + " argument value of type [" +
ObjectUtils.nullSafeClassName(argValue) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
}
//返回解析好的参数
return resolvedArgs;
} DefaultListableBeanFactory.resolveDependency public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
//获取参数名
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//如果对应的字段或参数类型是Option类型的,那么创建Option,对应的值用get获取,其实内部的值依然是调用 doResolveDependency获取的
if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
}
//如果这个字段或参数是对象工厂,那么返回依赖工厂,对应的值用个getObject获取
else if (ObjectFactory.class == descriptor.getDependencyType()) {
return new DependencyObjectFactory(descriptor, beanName);
}
//如果这个字段或参数类型为javax.inject.Provider,那么返回DependencyProvider,通过get获取值
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
if (result == null) {
//解析依赖
result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
}
return result;
}
} DefaultListableBeanFactory.doResolveDependency public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
//获取字段或方法参数的类型
Class<?> type = descriptor.getDependencyType();
//获取@Value注解的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//如果从@Value中获取到了数据,那么就解析${}占位符。
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
//动态语言解析
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
//转换类型后返回
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//如果是数组,那么获取到对应数组类型,然后到BeanFactory中获取到对应的类型
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
//获取符合类型的候选的对象
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
if (matchingBeans.isEmpty()) {
//如果这个字段或参数是必须的,又没有值,那么只好报错了
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
//转换类型
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof Object[]) {
Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
//处理集合类型
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getCollectionType();
if (elementType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
}
return null;
}
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof List) {
Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
、 //处理Map类型
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> keyType = descriptor.getMapKeyType();
if (String.class != keyType) {
if (descriptor.isRequired()) {
throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
"] must be [java.lang.String]");
}
return null;
}
Class<?> valueType = descriptor.getMapValueType();
if (valueType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
}
return null;
}
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(type, "", descriptor);
}
return null;
}
//如果匹配的bean大于一个,那么就查看是否配置了primary属性,如果有就使用primary的那个,没有就报错。
if (matchingBeans.size() > 1) {
String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (primaryBeanName == null) {
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(primaryBeanName);
}
return matchingBeans.get(primaryBeanName);
}
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
if (autowiredBeanNames != null) {
autowiredBeanNames.add(entry.getKey());
}
return entry.getValue();
}
}

bean的创建(五)第二部分 寻找bean的工厂方法实例化的更多相关文章

  1. 创建类模式(一):工厂方法(Factory Method)

    定义 此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦.复用和方便后期维护拓展的目的. 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心 ...

  2. Spring 源码(17)Spring Bean的创建过程(8)Bean的初始化

    知识回顾 Bean的创建过程会经历getBean,doGetBean,createBean,doCreateBean,然后Bean的创建又会经历实例化,属性填充,初始化. 在实例化createInst ...

  3. IoC容器装配Bean(xml配置方式)(Bean的生命周期)

    1.Spring管理Bean,实例化Bean对象 三种方式 第一种:使用类构造器实例化(默认无参数) package cn.itcast.spring.initbean; /** * 使用构造方法 实 ...

  4. Spring学习笔记之 Spring IOC容器(一)之 实例化容器,创建JavaBean对象,控制Bean实例化,setter方式注入,依赖属性的注入,自动装配功能实现自动属性注入

    本节主要内容:       1.实例化Spring容器示例    2.利用Spring容器创建JavaBean对象    3.如何控制Bean实例化    4.利用Spring实现bean属性sett ...

  5. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

  6. Spring Bean学习创建及使用<一>

    转自:http://glzaction.iteye.com/blog/1299441 Spring中依赖注入有三种注入方式: 一.构造器注入: 二.设值注入(setter方式注入): 三.Feild方 ...

  7. Spring学习--静态工厂方法、实例工厂方法创建 Bean

    通过调用静态工厂方法创建 bean: 调用静态工厂方法创建 bean 是将对象创建的过程封装到静态方法中 , 当客户端需要对象时 , 只需要简单地调用静态方法 , 而不需要关心创建对象的细节. 要声明 ...

  8. Spring5参考指南:Bean的创建

    文章目录 Spring容器中的Bean Bean的命名 Bean的实例化 Spring容器中的Bean Bean在Spring中就是一个业务组件,我们通过创建各种Bean来完成最终的业务逻辑功能. 在 ...

  9. Spring 源码(11)Spring Bean 的创建过程(2)

    Spring Bean 的创建过程介绍了FactoryBean 的创建方式,那么接下来介绍不是FactoryBean的创建方式,在创建过程中,又会分为单例的Bean的创建,原型类型的Bean的创建等. ...

随机推荐

  1. Java开发桌面程序学习(九)——JavaFxTemplate JavaFx模版 更简单进行JavaFx程序开发

    JavaFxTemplate 使用说明 项目基于maven,请确保maven配置成功,否则,可能会出现问题 项目内置了commons-io的jar包,Jfoenix的jar包以及常用的工具类JFxUt ...

  2. 视频直播:Windows中各类画面源的截取和合成方法总结

    当今,视频直播技术和实时音视频技术已经是很多行业必备,典型的应用场景有教育直播.远程视频会议.互联网娱乐等.在移动端发起直播,其画面源的种类是十分有限的,无非是取摄像头.截屏等.PC端由于其系统资源充 ...

  3. 微信商城小程序 带java后台源码

    微信小程序商城(Java版) 技术选型 1 后端使用技术 1.1 spring-web-4.0.2.RELEASE 1.2 mybatis3.2.8 1.3 shiro1.2.3 1.4 servle ...

  4. spring 5.x 系列第4篇 —— spring AOP (代码配置方式)

    文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 2.5 切面执行顺 ...

  5. 【设计模式】行为型07备忘录模式(Memento Pattern)

    参考地址:http://www.runoob.com/design-pattern/memento-pattern.html 对原文总结调整,以及修改代码以更清晰的展示: 备忘录模式(快照模式):   ...

  6. JavaScript 词法作用域不完全指北

    在 JavaScript 作用域不完全指北 中,我们介绍了作用域的概念以及 JavaScript 引擎.编译器和作用域的关系.作用域有两种主要的工作模型:词法作用域和动态作用域.其中最为普遍的也是大多 ...

  7. leadcode的Hot100系列--617. 合并二叉树

    合并,就是两个树的结构交集部分,数据相加,否则,取非空部分. 所以,这里相当于是对两棵树同时遍历: 如果两棵树节点都不为空,则数据相加, 否则,直接指针把不为空的节点复制过来. 注:这里没有申请内存, ...

  8. Hive入门(三)分桶

    1 什么是分桶 上一篇说到了分区,分区中的数据可以被进一步拆分成桶,bucket.不同于分区对列直接进行拆分,桶往往使用列的哈希值进行数据采样.在分区数量过于庞大以至于可能导致文件系统崩溃时,建议使用 ...

  9. ZOJ 3963:Heap Partition(贪心+set+并查集)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3963 题意:给出一个n个数的序列,可以在其中找一个子序列建堆,并且堆中的父 ...

  10. elasticsearch 集群部署,版本 5.5.0

    准备说明: 两台服务器 Ip分别为 192.168.239.78(主),192.168.239.49(从) 主服务器上配置如下:1.上传es5.5.0版本至主服务器2.解压 unzipunzip el ...