一核心概念
控制反转:将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.exception.BeanDefinitionRegistException;
import core.ioc.BeanDefinition;
import core.ioc.BeanDefinitionRegistry;
import core.ioc.BeanFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.ws.WebServiceException;
import java.io.Closeable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
private final Log logger = LogFactory.getLog(DefaultBeanFactory.class);
//存在beanDefinition的缓存
private Map<String,BeanDefinition> beanDefinitionMap= new ConcurrentHashMap<>(256);
//存放单例bean实例的缓存
private Map<String,Object> beanMap = new ConcurrentHashMap<>(256);
//获取bean实例
public Object getBean(String name) throws Exception {
return this.doGetBean(name);
}
protected Object doGetBean(String beanName) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//验证bean不能为空
Objects.requireNonNull(beanName,"beanName不能为空");
//查看是否已经创建,如果已经创建则直接从缓存中取得返回
Object instance = beanMap.get(beanName);
if(null!=instance){
return instance;
}
//如果没有创建,则需要创建,
BeanDefinition bd = this.getBeanDefinition(beanName);
Objects.requireNonNull(bd,"beanDefinition 不能为空");
Class<?> type=bd.getBeanClass();
if(type!=null){
if(StringUtils.isBlank(bd.getFactoryMethodName())){
//构造方法来构造对象
instance =this.createInstanceByConstructor(bd);
}else{
//通过静态工厂方法创建对象
instance=this.createInstanceByStaticFactoryMethod(bd);
}
}else{
//通过工厂bean方式来构造对象
instance=this.createInstanceByFactoryBean(bd);
}
//执行初始化方法,比如说给属性赋值等
this.doInit(bd,instance);
//如果是单例,则将bean实例放入缓存中
if(bd.isSingleton()){
beanMap.put(beanName,instance);
}
return instance;
}
/**
* 通过构造方法来构造对象
* @param bd dean定义
* @return bean实例
* @throws IllegalAccessException
* @throws InstantiationException
*/
private Object createInstanceByConstructor(BeanDefinition bd) throws IllegalAccessException, InstantiationException {
return bd.getBeanClass().newInstance();
}
/**
* 通过静态工厂方法创建bean
* @param bd bean定义
* @return bean 实例
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> type=bd.getBeanClass();
Method m=type.getMethod(bd.getFactoryMethodName(),null);
return m.invoke(type,null);
}
/**
* 通过工厂bean 方式来构造对象
* @param bd
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
private Object createInstanceByFactoryBean(BeanDefinition bd) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
Object factoryBean =this.doGetBean(bd.getFactoryBeanName());
Method m=factoryBean.getClass().getMethod(bd.getFactoryMethodName(),null);
return m.invoke(factoryBean,null);
}
/**
* 初始化
* @param bd
* @param instance
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private void doInit(BeanDefinition bd,Object instance) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
if(StringUtils.isNotBlank(bd.getInitMehtodName())){
Method m=instance.getClass().getMethod(bd.getInitMehtodName(),null);
m.invoke(instance,null);
}
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionRegistException {
Objects.requireNonNull(beanName,"注册bean需要给入beanName");
Objects.requireNonNull(beanDefinition,"注册bean需要给入beanDefinition");
//检验给如的bean是否合法
if(!beanDefinition.validata()){
throw new BeanDefinitionRegistException(String.format("名字为[%s]的bean的定义不合法:%s",beanName,beanDefinition));
}
//验证beanDefinition已经存在
if(this.containBeanDefinition(beanName)){
throw new BeanDefinitionRegistException(String.format("名字为[%s]的bean定义已经存在:%s",
beanName,this.getBeanDefinition(beanName)));
}
this.beanDefinitionMap.put(beanName,beanDefinition);
}
/**
* 获取beanDefinition
* @param beanName bean的名称 唯一标识
* @return beanDefinition
*/
@Override
public BeanDefinition getBeanDefinition(String beanName) {
return this.beanDefinitionMap.get(beanName);
}
/**
* 验证beanDefinition是否已经存在
* @param beanName bean的名称 唯一标识
* @return true:已存在 false:不存在
*/
@Override
public boolean containBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
/**
* 执行指定的销毁方法
* @throws WebServiceException
*/
@Override
public void close() throws WebServiceException {
//执行单例实例的销毁方法
for(Map.Entry<String,BeanDefinition> e:this.beanDefinitionMap.entrySet()){
String beanName=e.getKey();
BeanDefinition bd=e.getValue();
if(bd.isSingleton() && StringUtils.isNotBlank(bd.getDestroyMethodName())){
Object instance = this.beanMap.get(beanName);
try {
Method m = instance.getClass().getMethod(bd.getDestroyMethodName());
m.invoke(instance,null);
} catch (NoSuchMethodException e1) {
logger.error(String.format("执行bean[%s] %s 的 销毁方法异常!",beanName,bd), e1);
e1.printStackTrace();
} catch (IllegalAccessException e1) {
logger.error(String.format("执行bean[%s] %s 的 销毁方法异常!",beanName,bd), e1);
e1.printStackTrace();
} catch (InvocationTargetException e1) {
logger.error(String.format("执行bean[%s] %s 的 销毁方法异常!",beanName,bd), e1);
e1.printStackTrace();
}
}
}
}
}
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;
}
}
原文出处:https://www.cnblogs.com/jjdyzz/p/12563342.html