原型模式(Prototype)-创建型(Creational)设计模式
今天早上起床,突然脑子里面想起来,AbstractBeanDefinition试下了Clonable接口,Spring里面是使用了原型模式
现在一看代码,发现还真是有,所以就记录下来。
org.springframework.beans.factory.support.AbstractBeanDefinition的代码
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { @Override public Object clone() { return cloneBeanDefinition(); } public abstract AbstractBeanDefinition cloneBeanDefinition(); /** * *实现的深克隆 */ protected AbstractBeanDefinition(BeanDefinition original) { setParentName(original.getParentName()); setBeanClassName(original.getBeanClassName()); setScope(original.getScope()); setAbstract(original.isAbstract()); setFactoryBeanName(original.getFactoryBeanName()); setFactoryMethodName(original.getFactoryMethodName()); setRole(original.getRole()); setSource(original.getSource()); copyAttributesFrom(original); if (original instanceof AbstractBeanDefinition) { AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original; if (originalAbd.hasBeanClass()) { setBeanClass(originalAbd.getBeanClass()); } if (originalAbd.hasConstructorArgumentValues()) { setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues())); } if (originalAbd.hasPropertyValues()) { setPropertyValues(new MutablePropertyValues(original.getPropertyValues())); } if (originalAbd.hasMethodOverrides()) { setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides())); } Boolean lazyInit = originalAbd.getLazyInit(); if (lazyInit != null) { setLazyInit(lazyInit); } setAutowireMode(originalAbd.getAutowireMode()); setDependencyCheck(originalAbd.getDependencyCheck()); setDependsOn(originalAbd.getDependsOn()); setAutowireCandidate(originalAbd.isAutowireCandidate()); setPrimary(originalAbd.isPrimary()); copyQualifiersFrom(originalAbd); setInstanceSupplier(originalAbd.getInstanceSupplier()); setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(originalAbd.isLenientConstructorResolution()); setInitMethodName(originalAbd.getInitMethodName()); setEnforceInitMethod(originalAbd.isEnforceInitMethod()); setDestroyMethodName(originalAbd.getDestroyMethodName()); setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod()); setSynthetic(originalAbd.isSynthetic()); setResource(originalAbd.getResource()); } else { setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues())); setPropertyValues(new MutablePropertyValues(original.getPropertyValues())); setLazyInit(original.isLazyInit()); setResourceDescription(original.getResourceDescription()); } } }
AbstractBeanDefinition的子类实现就是调用,AbstractBeanDefinition里面的#AbstractBeanDefinition(BeanDefinition original)实现深克隆
看看org.springframework.beans.factory.support.GenericBeanDefinition的实现方法
public GenericBeanDefinition(BeanDefinition original) { super(original); }
-------------------------------------------------------------------
现在说说本场主角,原型模式,分为:浅克隆、深克隆
浅克隆:简单的说,就是只克隆基本属性,对象属性没有进行克隆,用的还是同一个,当对象属性改变,所有的基于浅克隆的对象属性值就都改变了
深克隆:简单的说,就是对象属性也进行克隆
简单代码实现:
public class ProtoypePraticeDay4 { public static class ConstructorArgumentValues{ public ConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) { } public ConstructorArgumentValues() { } } public static class PropertyValues{ public PropertyValues(PropertyValues propertyValues) { } public PropertyValues() { } } public static interface IncenseDefinition{ public Integer getRole(); public void setRole(Integer role); public String getScope(); public void setScope(String scope); public String getParentName() ; public void setParentName(String parentName); public Boolean getPrimaryFlag() ; public void setPrimaryFlag(Boolean primaryFlag); public Boolean getAutowiredCandidateFlag(); public void setAutowiredCandidateFlag(Boolean autowiredCandidateFlag); public Boolean getLazyInitFlag() ; public void setLazyInitFlag(Boolean lazyInitFlag); public Boolean getAbstractFlag() ; public void setAbstractFlag(Boolean abstractFlag) ; public String getIncenseFactoryBeanName() ; public void setIncenseFactoryBeanName(String incenseFactoryBeanName); public String getIncenseFactoryMethodName() ; public void setIncenseFactoryMethodName(String incenseFactoryMethodName); public String getIncenseClassName(); public void setIncenseClassName(String incenseClassName); public ConstructorArgumentValues getConstructorArgumentValues(); public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues); public PropertyValues getPropertyValues() ; public void setPropertyValues(PropertyValues propertyValues); } /** * 实现Cloneable接口 */ public static abstract class AbstractIncenseDefinition implements IncenseDefinition, Cloneable{ private Boolean primaryFlag; private Boolean autowiredCandidateFlag; private Boolean lazyInitFlag; private Boolean abstractFlag; private String incenseFactoryBeanName; private String incenseFactoryMethodName; private String incenseClassName; private ConstructorArgumentValues constructorArgumentValues; private PropertyValues propertyValues; /** * 父incenseName */ private String parentName; private String scope; private Integer role; @Override public Integer getRole() { return role; } @Override public void setRole(Integer role) { this.role = role; } @Override public String getScope() { return scope; } @Override public void setScope(String scope) { this.scope = scope; } @Override public String getParentName() { return parentName; } @Override public void setParentName(String parentName) { this.parentName = parentName; } @Override public Boolean getPrimaryFlag() { return primaryFlag; } @Override public void setPrimaryFlag(Boolean primaryFlag) { this.primaryFlag = primaryFlag; } @Override public Boolean getAutowiredCandidateFlag() { return autowiredCandidateFlag; } @Override public void setAutowiredCandidateFlag(Boolean autowiredCandidateFlag) { this.autowiredCandidateFlag = autowiredCandidateFlag; } @Override public Boolean getLazyInitFlag() { return lazyInitFlag; } @Override public void setLazyInitFlag(Boolean lazyInitFlag) { this.lazyInitFlag = lazyInitFlag; } @Override public Boolean getAbstractFlag() { return abstractFlag; } @Override public void setAbstractFlag(Boolean abstractFlag) { this.abstractFlag = abstractFlag; } @Override public String getIncenseFactoryBeanName() { return incenseFactoryBeanName; } @Override public void setIncenseFactoryBeanName(String incenseFactoryBeanName) { this.incenseFactoryBeanName = incenseFactoryBeanName; } @Override public String getIncenseFactoryMethodName() { return incenseFactoryMethodName; } @Override public void setIncenseFactoryMethodName(String incenseFactoryMethodName) { this.incenseFactoryMethodName = incenseFactoryMethodName; } @Override public String getIncenseClassName() { return incenseClassName; } @Override public void setIncenseClassName(String incenseClassName) { this.incenseClassName = incenseClassName; } @Override public ConstructorArgumentValues getConstructorArgumentValues() { return constructorArgumentValues; } @Override public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) { this.constructorArgumentValues = constructorArgumentValues; } @Override public PropertyValues getPropertyValues() { return null; } @Override public void setPropertyValues(PropertyValues propertyValues) { } /** * 克隆抽象方法,子类去实现 * @return */ public abstract AbstractIncenseDefinition cloneIncenseDefinition(); /** * 使用cloneIncenseDefinition()实现深克隆 * @return * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { return cloneIncenseDefinition(); } public AbstractIncenseDefinition() { } /** * 这就是真正的深克隆构造方法实现 * @param original */ public AbstractIncenseDefinition(IncenseDefinition original){ setParentName(original.getParentName()); setIncenseClassName(original.getIncenseClassName()); setScope(original.getScope()); setAbstractFlag(original.getAbstractFlag()); setIncenseFactoryBeanName(original.getIncenseFactoryBeanName()); setIncenseFactoryMethodName(original.getIncenseFactoryMethodName()); setRole(original.getRole()); if (original instanceof AbstractIncenseDefinition){ AbstractIncenseDefinition abstractIDF = (AbstractIncenseDefinition) original; setConstructorArgumentValues(new ConstructorArgumentValues(abstractIDF.constructorArgumentValues)); setPropertyValues(new PropertyValues(abstractIDF.getPropertyValues())); setLazyInitFlag(abstractIDF.getLazyInitFlag()); //还有设置很多属性 }else{ //不是AbstractIncenseDefinition这一类型的,就只能克隆IncenseDefinition上定义的方法 setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues())); setPropertyValues(new PropertyValues(original.getPropertyValues())); } } } public static class GenericIncenseDefinition extends AbstractIncenseDefinition{ private String parentName; @Override public String getParentName() { return parentName; } @Override public void setParentName(String parentName) { this.parentName = parentName; } public GenericIncenseDefinition() { super(); } public GenericIncenseDefinition(AbstractIncenseDefinition original) { super(original); } /** * 子类调用父类的构造方法 * 这里也是精髓,直接new GenericIncenseDefinition(this) * 没有在父类里面去创建一个对象出来,再返回,我也是第一次见过这种,涨见识了 * @return */ @Override public AbstractIncenseDefinition cloneIncenseDefinition() { return new GenericIncenseDefinition(this); } } }
爽,那现在来运行看看
public static void main(String[] args) { GenericIncenseDefinition genericIncenseDefinition = new GenericIncenseDefinition(); genericIncenseDefinition.setParentName("testService"); genericIncenseDefinition.setAbstractFlag(false); genericIncenseDefinition.setPrimaryFlag(false); genericIncenseDefinition.setConstructorArgumentValues(new ConstructorArgumentValues()); GenericIncenseDefinition cloneIncenseDefiniton = (GenericIncenseDefinition) genericIncenseDefinition.cloneIncenseDefinition(); System.out.println(genericIncenseDefinition); System.out.println(cloneIncenseDefiniton); System.out.println(genericIncenseDefinition.getConstructorArgumentValues()); System.out.println(cloneIncenseDefiniton.getConstructorArgumentValues()); }
结果如下,跟预想的一般,打印出来的hashCode地址是不一样的。
giao,这个花了我一个小时的时间整理出来,还行吧,有空有问题,望指出啊
com.lg.designpattern.prototype.ProtoypePraticeDay4$GenericIncenseDefinition@7f31245a
com.lg.designpattern.prototype.ProtoypePraticeDay4$GenericIncenseDefinition@6d6f6e28
com.lg.designpattern.prototype.ProtoypePraticeDay4$ConstructorArgumentValues@135fbaa4
com.lg.designpattern.prototype.ProtoypePraticeDay4$ConstructorArgumentValues@45ee12a7