一、代码实例

  在我们分析spring的IOC源码的时候,发现除了配置标准的bean,并且通过getBean(beanName)的方法获取到一个bean的实例外,似乎还有这不少其他获取的方法,例如在第四节,我们发现得到bean实例后,在第26节,会判断是否继承了FactoryBean,然后调用它的方法获取真实的bean,在配置文件中我们发现一个factory-bean方法,这些都说明,我们应该可以使用一个beanFactory获取一个bean,此节重点讨论这部分的实现。

  代码如下:

  1、car类

package com.zjl.factorybean;

public class Car {
public Car(String name) {
this.name=name;
}
String name;
public void run(){
System.out.println(this.name+" is running");
}
}

  2、person类

package com.zjl.factorybean;

public class Person {
public Person(String name) {
this.name=name;
}
public String name;
public int age; public Car car; public void sayHello(){
System.out.println(this.name+" say hello");
}
public Car createCar(){
return new Car("奥迪");
}
}

  3、用来获取person的FactoryBean,必须继承FactoryBean接口 

package com.zjl.factorybean;
import org.springframework.beans.factory.FactoryBean; public class PersonFactory implements FactoryBean<Person> {
String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public Person getObject() throws Exception {
return new Person(name);
} @Override
public Class<Person> getObjectType() {
return Person.class;
} @Override
public boolean isSingleton() {
return true;
} }

  4、配置文件

 <bean id="personFactory" class="com.zjl.factorybean.PersonFactory">
<property name="name" value="zhangsan"></property>
</bean> <bean id="car" factory-method="createCar" factory-bean="personFactory"></bean>

  5、测试类

package com.zjl.factorybean;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource; public class Test {
public static void main(String[] args) throws Exception {
DefaultListableBeanFactory beanFacory=new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFacory);
reader.loadBeanDefinitions(new ClassPathResource("factorybean.xml")); Person person=(Person)beanFacory.getBean("personFactory");
person.sayHello();
Person person2=(Person)beanFacory.getBean("personFactory");
System.out.println("person==person2 is "+(person==person2)); Car car=(Car)beanFacory.getBean("car");
car.run();
Car car2=(Car)beanFacory.getBean("car");
System.out.println("car==car2 is "+(car==car2));
}
}

  6、测试结果

zhangsan say hello
person==person2 is true
奥迪 is running
car==car2 is true

  7、结论

  我们可以看到:

  a)通过getBean(beanName)方法获取到的直接就是Person的实例,而不是BeanFactory或者PersonFactory的实例。

  b)每次获取到的Person实例都是同一个,根据接口中的方法isSingleton方法,猜测于此有关

  c)bean的id为car,并没有配置我们常见的class配置,他应该是执行了Person的createCar方法

  d)car也遵循单例模式

二、FactoryBean代码解析

  1、通过我们对bean的加载过程,发现所有的配置无论是spring默认bean的 配置,还是客户自定义的配置均无差别的被解析后存放在beanDefinitionMap中,所以解析配置文件过程不再重复。

  2、Person person=(Person)beanFacory.getBean("personFactory");生成bean过程与第四部分重复的跳过

  3、来到bean生成实例后的地方

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd)

  4、进入方法,判断如果是bean不是FactoryBean的实例且beanName是&开头,抛出错误。是FactoryBean的实例,且以&开头,则直接返回实例。

    将实例转化为FactoryBean的实例,并且调用getObjectFromFactoryBean(factory, beanName, !synthetic)方法

  注:也就是我们要获得定义的通过personFactory返回PersonFactory的实例,可以使用beanFacory.getBean("&personFactory")进行获取,然后调用getObject也可以返回Person的实例,不过这个需要自己控制单例模式

    protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}//bean不是FactoryBean的实例且beanName是&开头,报错 // Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
     //bean是FactoryBean的实例,且beanName以&开头,返回实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
} Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

  5、调用factory实例的isSingleton方法和containsSingleton(beanName),判断是否是单例模式,单例模式的话,从factoryBeanObjectCache中尝试读取,否则直接生成。

  注:我们可以看到,通过FactoryBean的对象是否是单例模式取决于bean定义的范围和方法isSingleton同时为单例才可以

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
            //入口,调用getObject方法
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}

  6、doGetObjectFromFactoryBean中调用getObject方法,返回实例

  7、调用bean后处理postProcessObjectFromFactoryBean并放入缓存factoryBeanObjectCache

  到此,我们已经获取到了真正的bean,并且也知道了怎么获取原来定义的FactoryBean的实例,但是,似乎少了一个方法,那就说FactoryBean中的getObjectType,我们需要回头去找哪里漏掉了

  我翻遍了源代码,并没有找到此方法调用的地方,事实上通过改动

    @Override
public Class<Car> getObjectType() {
return Car.class;
}

或者

    @Override
public Class<Person> getObjectType() {
return null;
}

都不会影响代码执行结果的正确性,那么我们猜想,是否仅仅是一个预留,并无实际用处,或者客户自定义使用方法。

三、FactoryBean实例

  在上一步查找源代码过程中,我们有了新的发现,spring自定义了抽象类AbstractFactoryBean和大量他的子类,包括我们常见的list,map,set,object等,我们也来研究下

1、首先是他的继承关系

public abstract class AbstractFactoryBean<T>
implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {

我们看到继承了几个熟悉的接口,包括FactoryBean和InitializingBean,还有几个BeanClassLoaderAware, BeanFactoryAware, DisposableBean,这些接口分别是:

FactoryBean:通过getObjectBean生成bean实例

InitializingBean:在实例化后执行afterPropertiesSet方法

以上我们比较熟悉,其余三个接口简单了解下

BeanClassLoaderAware:注入classLoad

BeanFactoryAware:注入一个BeanFactory

DisposableBean:销毁bean默认调用destroy方法

我们这里重点关注FactoryBean的三个接口实现:

2、是否单例,通过外部注入

    public boolean isSingleton() {
return this.singleton;
}

3、getObject方法,如果是单例且已经创建,返回单例模式,未创建调用getEarlySingletonInstance方法,不是单例模式,调用createInstance方法

    @Override
public final T getObject() throws Exception {
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
return createInstance();
}
}

4、getEarlySingletonInstance方法,通过第5步判断,是否为接口,如果是通过动态代理,创建对象

    private T getEarlySingletonInstance() throws Exception {
Class<?>[] ifcs = getEarlySingletonInterfaces();
if (ifcs == null) {
throw new FactoryBeanNotInitializedException(
getClass().getName() + " does not support circular references");
}
if (this.earlySingletonInstance == null) {
this.earlySingletonInstance = (T) Proxy.newProxyInstance(
this.beanClassLoader, ifcs, new EarlySingletonInvocationHandler());
}
return this.earlySingletonInstance;
}

5、此处调用getObjectType,判断是否为空或者是否为接口,如果是,返回,否则为空

    protected Class<?>[] getEarlySingletonInterfaces() {
Class<?> type = getObjectType();
return (type != null && type.isInterface() ? new Class<?>[] {type} : null);
}

6、动态代理的InvocationHandler 类,似乎什么都没干,存疑

private class EarlySingletonInvocationHandler implements InvocationHandler {

        @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (ReflectionUtils.isEqualsMethod(method)) {
// Only consider equal when proxies are identical.
return (proxy == args[0]);
}
else if (ReflectionUtils.isHashCodeMethod(method)) {
// Use hashCode of reference proxy.
return System.identityHashCode(proxy);
}
else if (!initialized && ReflectionUtils.isToStringMethod(method)) {
return "Early singleton proxy for interfaces " +
ObjectUtils.nullSafeToString(getEarlySingletonInterfaces());
}
try {
return method.invoke(getSingletonInstance(), args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}

分析到这里,似乎这个类什么都没做,我们具体看个实例类ListFactoryBean,此类注入了以下参数:

a、sourceList是一个list

b、targetListClass是一个Class

c、重写了createInstance(),将sourceList修改后注入

public class ListFactoryBean extends AbstractFactoryBean<List<Object>> {

    private List<?> sourceList;

    @SuppressWarnings("rawtypes")
private Class<? extends List> targetListClass; /**
* Set the source List, typically populated via XML "list" elements.
*/
public void setSourceList(List<?> sourceList) {
this.sourceList = sourceList;
} /**
* Set the class to use for the target List. Can be populated with a fully
* qualified class name when defined in a Spring application context.
* <p>Default is a {@code java.util.ArrayList}.
* @see java.util.ArrayList
*/
@SuppressWarnings("rawtypes")
public void setTargetListClass(Class<? extends List> targetListClass) {
if (targetListClass == null) {
throw new IllegalArgumentException("'targetListClass' must not be null");
}
if (!List.class.isAssignableFrom(targetListClass)) {
throw new IllegalArgumentException("'targetListClass' must implement [java.util.List]");
}
this.targetListClass = targetListClass;
} @Override
@SuppressWarnings("rawtypes")
public Class<List> getObjectType() {
return List.class;
} @Override
@SuppressWarnings("unchecked")
protected List<Object> createInstance() {
if (this.sourceList == null) {
throw new IllegalArgumentException("'sourceList' is required");
}
List<Object> result = null;
if (this.targetListClass != null) {
result = BeanUtils.instantiateClass(this.targetListClass);
}
else {
result = new ArrayList<Object>(this.sourceList.size());
}
Class<?> valueType = null;
if (this.targetListClass != null) {
valueType = GenericCollectionTypeResolver.getCollectionType(this.targetListClass);
}
if (valueType != null) {
TypeConverter converter = getBeanTypeConverter();
for (Object elem : this.sourceList) {
result.add(converter.convertIfNecessary(elem, valueType));
}
}
else {
result.addAll(this.sourceList);
}
return result;
} }

ListFactoryBean

7、配置文件

        <bean id="list" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="targetListClass">
<value>java.util.ArrayList</value>
</property>
<property name="sourceList">
<list>
<value>zhangsan</value>
<value>lisi</value>
<value>wangwu</value>
</list>
</property>
</bean>

8、测试代码

    public static void main(String[] args) throws Exception {
DefaultListableBeanFactory beanFacory=new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFacory);
reader.loadBeanDefinitions(new ClassPathResource("factorybean.xml")); @SuppressWarnings("unchecked")
List<String> list=(List<String>)beanFacory.getBean("list");
System.out.println(list.toString()); }

四、factory-bean的源码解析

1、与之前解析类似,直到进入,如果有beancalss,直接返回beanClass,此处返回值为null

protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
@Override
public Class<?> run() throws Exception {
return doResolveBeanClass(mbd, typesToMatch);
}
}, getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}

2、开始创建bean实例,判断是否有beanClass,如果有FactoryMethodname,调用instantiateUsingFactoryMethod(beanName, mbd, args)

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, 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());
} if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

3、进入instantiateUsingFactoryMethod方法,判断factoryBeanName是否为空,如果不为空,判断是否为自身,自身则报错。不是自身,获取factoryBean和factoryClass,设定为非静态;如果factoryBeanName为空,且没有classname则报错,有的话,获得factoryClass,设定为静态

注:此处应该是由两种方式,一种通过其他bean来生成,一种是通过class的静态方法生成

String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
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;
}

4、从factoryClass中检查是否有FactoryBeanMethod,此处获得的是数组,说明可能可以根据重写的方法和参数生成不同的bean

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()]);
AutowireUtils.sortFactoryMethods(candidates);

5、进入instantiate,反射生成真正的bean

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object... args) { try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
}
});
}
else {
ReflectionUtils.makeAccessible(factoryMethod);
} Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
return factoryMethod.invoke(factoryBean, args);
}
finally {
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}

到这里bean就真正的生成了

五、bean-factory验证

主要需要验证的有两点:

1、如过没有factory-bean,我们可以使用一个class的静态方法进行生成bean

2、可以使用多个重写的方法选择进行生成bean,参数可以从外部传递

我们增加一个CarFactory类,其中有一个静态方法createCar()

public class CarFactory {
public static Car createCar(){
return new Car();
}
}

修改Car类,与一般的bean相同

package com.zjl.factorybean;

public class Car {
public Car() {
}
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void run(){
System.out.println(this.name+" is running");
}
}

编写配置文件

   <bean id="car" factory-method="createCar" class="com.zjl.factorybean.CarFactory"><!-- 使用class的静态方法 -->
<property name="name" value="奔驰"></property><!-- 属性注入 -->
</bean>

测试类:

public class Test {
public static void main(String[] args) throws Exception {
DefaultListableBeanFactory beanFacory=new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFacory);
reader.loadBeanDefinitions(new ClassPathResource("factorybean.xml")); Car car=(Car)beanFacory.getBean("car");
car.run();
Car car2=(Car)beanFacory.getBean("car");
System.out.println("car==car2 is "+(car==car2));
}
}

结果:

奔驰 is running
car==car2 is true

可以看到,结果跟我们在阅读源码时候的猜想完全一致

六、总结

1、FactoryBean与factory-bean的作用都是通过其他的一个bean工厂产生一个真实的bean,不同的是,FactoryBean是使用了spring默认的接口,具有一定侵入性,对框架造成依赖,factory-bean不会改变代码接口,属于注入方式。spring中很多类似的组队,比如init-method和InitializingBean。

2、从原则上,我们使用spring,很大的优点在于它没有侵略性。那么为什么会提供接口形式呢。接口形式更倾向于框架的使用,比如spirng的另一个重要的特性AOP,框架编写了AOPFactoryBean,我们不需要知道他内部实现,也不会获取他的实力,只需要配置它需要代理的类和接口,便可以成功返回一个真实的bean,也就是目标类的代理类,从而完成各种工作。

3、可以说spirng的很多扩展工作都是基于预留接口提供,同时新扩展的功能也会提供新的预留接口,比如aop的切面等。

[spring源码学习]六、IOC源码-BeanFactory和factory-bean的更多相关文章

  1. spring cloud深入学习(四)-----eureka源码解析、ribbon解析、声明式调用feign

    基本概念 1.Registe 一一服务注册当eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据,比如IP地址.端口.运行状况指标的Uri.主页地址 ...

  2. Spring Ioc源码分析系列--Ioc源码入口分析

    Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...

  3. Spring5.0源码学习系列之浅谈BeanFactory创建

    Spring5.0源码学习系列之浅谈BeanFactory创建过程 系列文章目录 提示:Spring源码学习专栏链接 @ 目录 系列文章目录 博客前言介绍 一.获取BeanFactory主流程 二.r ...

  4. Spring源码学习之IOC容器实现原理(一)-DefaultListableBeanFactory

    从这个继承体系结构图来看,我们可以发现DefaultListableBeanFactory是第一个非抽象类,非接口类.实际IOC容器.所以这篇博客以DefaultListableBeanFactory ...

  5. Spring源码学习之IOC实现原理(二)-ApplicationContext

    一.Spring核心组件结构 总的来说Spring共有三个核心组件,分别为Core,Context,Bean.三大核心组件的协同工作主要表现在 :Bean是包装我们应用程序自定义对象Object的,O ...

  6. 【SSH进阶之路】Spring的IOC逐层深入——源码解析之IoC的根本BeanFactory(五)

    我们前面的三篇博文,简单易懂的介绍了为什么要使用IOC[实例讲解](二).和Spring的IOC原理[通俗解释](三)以及依赖注入的两种常用实现类型(四),这些都是刚开始学习Spring IoC容器时 ...

  7. 框架源码系列七:Spring源码学习之BeanDefinition源码学习(BeanDefinition、Annotation 方式配置的BeanDefinition的解析)

    一.BeanDefinition 1. bean定义都定义了什么? 2.BeanDefinition的继承体系  父类: AttributeAccessor: 可以在xml的bean定义里面加上DTD ...

  8. 【 js 基础 】【 源码学习 】backbone 源码阅读(一)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

  9. 【 js 基础 】【 源码学习 】backbone 源码阅读(二)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(source-code-study)进行参考交流,有详细的源码注释,以及知识总结,同时 ...

随机推荐

  1. SecureCRT中设置 \n 为回车换行,和 \r\n 的行为一致

    勾上途中红框的选项即可

  2. JS打开新页面跳转

      有时候使用js进行页面跳转,想使用 a 标签中 target="_blank" 形式,跳转打开一个新的页面. 可以使用以下脚本,创建一个 a标签,然后模拟点击操作. 代码如下: ...

  3. BZOJ2802——[Poi2012]Warehouse Store

    1.题目巨短,自己看看吧 2.分析:这道题,想了半天dp还是想不到,最后看题解发现是个贪心的思想,我们维护一个堆,如果这个人不能加入就把他和堆上最大的进行比较,然后搞搞就行了 #include < ...

  4. php获取用户 地区 、ip地址

    header("Content-type: text/html; charset=utf-8"); function getCity($ip = '')//获取地区 { if($i ...

  5. 解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。

    解决mysql Table 'xxx' is marked as crashed and should be repaired的问题. 某个表在进行数据插入和更新时突然出现Table 'xxx' is ...

  6. sql server 2008 R2配置管理

    安装vs2013后,sql server 2008R2配置管理提示“远程过程调用失败” 这是因为vs2013自带的Microsoft SQL Server 2012Local DB与之冲突. 通过升级 ...

  7. mysql 命令导入导出

    导出 mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u root -p dataname >xxx.sql 导入 mysql>source ...

  8. 在c#中的TextBox响应回车键发出“咚”的一声解决方法

    在Win7系统的VS2012下的Form中,响应TextBox的KeyDown事件后,当按下回车键时发出"咚"的一声,百度后得到一下这样一个说法: 这是对于 windows 窗口标 ...

  9. memcache入门笔记

    向memcached保存数据时可以指定期限(秒).不指定期限时,memcached按照LRU算法保存数据. 这三个方法的区别如下: 选项 说明 add 仅当存储空间中不存在键相同的数据时才保存 rep ...

  10. 【转】linux sort 命令详解

    sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始! 1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按AS ...