spring最核心思想--ioc控制反转,
spring最核心思想--ioc控制反转,
一核心概念
控制反转:将bean的生成交给容器,程序可以从容器中获取指定的bean。
个人理解:此优势也是spring能够流行并成为java主流框架的主要原因,java是帮助java程序员以对象的方式管理 内存,而spring则是一个管理对象的框架。如果使用spring,在开发中基本上不需要考虑内存相关的问题。
接下来从一个设计者的思路去交流下spring的设计思路
二需求
基于以上的需求,我们需要做的核心的需求的是:生成,管理bean,向使用者提供。
三设计
看到这,是不是第一反应就是可以用工厂模式,没错,spring框架中针对此设计也是工厂模式。核心类为Beanactory,核心方法为getBean()。
1 public interface BeanFactory { 2 /** 3 * 获取bean 4 * @param name bean的名字 5 * @return bean 实例 6 * @throws Exception 7 */ 8 Object getBean(String name) throws Exception; 9 }
现在有个工厂,同时我们面对2个问题:
1BeanFactory如何知道生成什么样的bean(bean是由用户指定的)?
2用户如何定义一个bean,便于用户使用也便于beanFactory?
接下来先考虑第二个问题,现在谁也不知道用户将定义怎样的bean,那就来个万能大法,先定义的一个接口专门做这个事,接口为BeanDefinition。
回到第一个问题,我们如何将BeanDefinition告诉给BeanFactory?解决这个问题同时我们还要考虑可扩展性。这个解决方案是注册模式。
public interface BeanDefinitionRegistry {
/**
* 注册bean定义
* @param beanName bean名称(bean的唯一标识)
* @param beanDefinition bean定义
* @throws BeanDefinitionRegistException 注册异常
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionRegistException;
}
每个bean通过BeanDefinitionRegistry接口通知给BeanFactory。
目前只剩下一个问题:BeanDefinition如何定义,通俗点就是BeanDefinition里面都有什么。
Bean生成都有哪些情况,
1是否单例
2bean类名
3生成方式:
3.1指定初始化方法
必须的信息:bean的类名
3.2通过工厂模式
3.2.1静态的
public class PersonFactory{
public static Person getPerson(){
return new Person();
}
}
3.2.2成员方法
public class PersonFactory{ public Person getPerson(){ return new Person(); } }
工厂模式下,必须获取的信息如下:工厂bean的命,工厂方法名
3.3new的方式
4销毁的方法
具体接口如下:
public interface BeanDefinition { String SCOPE_SINGLETION = "singleton"; String SCOPE_PROTOTYPE = "prototype"; /** * 类 */ Class<?> getBeanClass(); /** * Scope */ String getScope(); /** * 是否单例 */ boolean isSingleton(); /** * 是否原型 */ boolean isPrototype(); /** * 工厂bean名 */ String getFactoryBeanName(); /** * 工厂方法名 */ String getFactoryMethodName(); /** * 初始化方法 */ String getInitMethodName(); /** * 销毁方法 */ String getDestroyMethodName(); /** * 校验bean定义的合法性 */ default boolean validate() { // 没定义class,工厂bean或工厂方法没指定,则不合法。 if (this.getBeanClass() == null) { if (StringUtils.isBlank(getFactoryBeanName()) || StringUtils.isBlank(getFactoryMethodName())) { return false; } } // 定义了类,又定义工厂bean,不合法 if (this.getBeanClass() != null && StringUtils.isNotBlank(getFactoryBeanName())) { return false; } return true; } }
ioc容器的主要设计均已设计完成。
简单的实现源代码如下:

package core.ioc.impl; import core.ioc.BeanDefinition; import org.apache.commons.lang3.StringUtils; public class GenericBeanDefinition implements BeanDefinition { private Class<?> beanClass; //是否为单例 private String scope = BeanDefinition.SCOPE_SINGLETION; //bean工厂的名称 private String factoryBeanName; //bean工厂方法名 private String factoryMethodName; //初始化方法 private String initMethodName; //销毁方法 private String destroyMethodName; /** * 自动生成设置的方法 start */ public void setBeanClass(Class<?> beanClass) { this.beanClass = beanClass; } public void setScope(String scope) { if(StringUtils.isNoneBlank(scope)){ this.scope = scope; } } public void setFactoryBeanName(String factoryBeanName) { this.factoryBeanName = factoryBeanName; } public void setFactoryMethodName(String factoryMethodName) { this.factoryMethodName = factoryMethodName; } public void setInitMethodName(String initMethodName) { this.initMethodName = initMethodName; } public void setDestroyMethodName(String destroyMethodName) { this.destroyMethodName = destroyMethodName; } /** * 自动生成设置的方法 end */ @Override public Class<?> getBeanClass() { return this.beanClass; } @Override public String getScope() { return this.scope; } @Override public boolean isSingleton() { return BeanDefinition.SCOPE_SINGLETION.equals(this.scope); } @Override public boolean isPrototype() { return BeanDefinition.SCOPE_PROTOTYPE.equals(this.scope); } @Override public String getFactoryBeanName() { return this.factoryBeanName; } @Override public String getFactoryMethodName() { return this.factoryMethodName; } @Override public String getInitMehtodName() { return this.initMethodName; } @Override public String getDestroyMethodName() { return this.destroyMethodName; } @Override public String toString() { return String.format("GenericBeanDefinition [beanClass=%s, scope=%s, factoryBeanName=%s, " + "factoryMethodName=%s, initMethodName=%s, destroyMethodName=%s]", beanClass,scope,factoryBeanName,factoryMethodName,initMethodName,destroyMethodName); } /** * 疑问: 为什么要重写equals 方法 * * 重写equals方法需要注意以下几点: * 1自反性:对于任何非空引用x,x.equals(x)应该返回true * 2对称:对于任何引用x,y,如果x.equals(y) 返回true,那么 y.equals(x)也应该返回true。 * 3传递性:对于任何引用x,y和z,如果x=y 为true,那么y=z也一定为true,x=z也一定为true。 * 4一致性:如果x和y引用的对象没有发生变化,那么返回调用x.equals(y),应该返回同样的结果。 * 5非空性:对于任意非空引用x,x.equals(null)应该返回false。 * * 重写equals方法,就必须重写hashCode * 原因是HashMap的需要 */ @Override public boolean equals(Object obj) { if(this==obj){ return true; } if(null==obj){ return false; } if(getClass() !=obj.getClass()){ return false; } GenericBeanDefinition other=(GenericBeanDefinition) obj; //验证每个属性是否相当,只有当每个属性均相等时,才是一个对象 if(beanClass ==null){ if(other.beanClass!=null){ return false; } }else if(!beanClass.equals(other.beanClass)){ return false; } if(destroyMethodName== null){ if(other.destroyMethodName!=null){ return false; } }else if(!destroyMethodName.equals(other.destroyMethodName) ){ return false; } if(factoryBeanName== null){ if(other.factoryBeanName!=null){ return false; } }else if(!factoryBeanName.equals(other.factoryBeanName) ){ return false; } if(factoryMethodName== null){ if(other.factoryMethodName!=null){ return false; } }else if(!factoryMethodName.equals(other.factoryMethodName) ){ return false; } if(initMethodName== null){ if(other.initMethodName!=null){ return false; } }else if(!initMethodName.equals(other.initMethodName) ){ return false; } if(scope== null){ if(other.scope!=null){ return false; } }else if(!scope.equals(other.scope) ){ return false; } return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((beanClass == null) ? 0 : beanClass.hashCode()); result = prime * result + ((destroyMethodName == null) ? 0 : destroyMethodName.hashCode()); result = prime * result + ((factoryBeanName == null) ? 0 : factoryBeanName.hashCode()); result = prime * result + ((factoryMethodName == null) ? 0 : factoryMethodName.hashCode()); result = prime * result + ((initMethodName == null) ? 0 : initMethodName.hashCode()); result = prime * result + ((scope == null) ? 0 : scope.hashCode()); return result; } }
相关文章
- 暂无相关文章
用户点评