反转:依赖对象的获得被反转,变为由自己创建,反转为从IOC容器中获取。 复制代码
1.代码更为简洁,不需要再去new需要的对象 2.面向接口编程,使用类和具体类解耦,易扩展,替换实现者 3.方便进行AOP增强(没有IOC就无法AOP) 复制代码
负责创建,管理类实例,向使用者提供实例 复制代码
IOC容器的工作:创建和管理Bean,它是一个工厂,负责对外提供Bean实例 复制代码
A:对外提供Bean实例,getBean()方法 复制代码
A:简单工厂模式中,当工厂能创建很多类产品,如果需要某类产品,需要告诉工厂 复制代码
A:各种类型的bean只能为Object<br><br> 复制代码
public interface BeanFactory { Object getBean(String name) throws Exception;} 复制代码
就是一个定义注册,我们可以给它定义一个定义注册接口,让bean定义传入bean工厂,告知工厂创建何种类型的Bean 复制代码
public interface BeanDefinitionRegistry {} 复制代码
注册,获取bean定义 复制代码
每个Bean要有一个独立的名称 复制代码
public interface BeanDefinitionRegistry { /** * 注册Bean * @param beanName * @param beanDefinition * @throws Exception */ void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws Exception; /** * 获取Bean * @param beanName * @return */ BeanDefinition getBeanDefinition(String beanName); /** * 判断Bean是否已经被注册 * @param beanName * @return */ Boolean containsBeanDefinition(String beanName); } 复制代码
告诉bean工厂该如何创建某类bean 复制代码
1.new 构造方法 2.工厂方法(静态,成员方法) 复制代码
1.new 构造方法(需要知道类名) 2.静态工厂方法(需要知道工厂类名,工厂方法名) 3.成员工厂方法(需要知道工厂类名--->工厂bean名,工厂方法名) 复制代码
否,因为有需要单例的情况 复制代码
1.获取bean的类名:getBeanClass() 2.获取工厂方法名:getFactoryMethodName() 3.获取工厂bean名:getFactoryBeanName() 4.是否是单例:getScope(){isSingleton(); isPrototype();} 复制代码
创建后可能需要的初始化 销毁时有可能出现的某些销毁逻辑(比如释放资源) 在bean定义提供让用户定制的初始化和销毁方法即可(getInitMethodName(),getDestroyMethodName()) 复制代码
public interface BeanDefinition { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; Class<?> getBeanClass(); String getScope(); boolean isSingleton(); boolean isPrototype(); String getFactoryBeanName(); String getFactoryMethodName(); String getInitMethodName(); String getDestoryMethodName(); //tips:java8开始就可以直接写接口默认方法了 default boolean validate(){ //class没指定,工厂bean或工厂method不指定皆为不合法情况 if (this.getBeanClass()==null){ if(StringUtils.isBlank(getFactoryBeanName())||StringUtils.isBlank(getFactoryMethodName())){ return false; } } //class和工厂bean同时存在 if (this.getBeanClass()!=null && StringUtils.isNotBlank(getFactoryBeanName())){ return false; } return true; } } 复制代码
import lombok.Data; import org.apache.commons.lang.StringUtils; @Data public class GeneralBeanDefinition implements BeanDefinition{ private Class<?> beanClass; private String scope = BeanDefinition.SCOPE_SINGLETON; private String factoryBeanName; private String factoryMethodName; private String initMethodName; private String destroyMethodName; public void setScope(String scope) { if (StringUtils.isNotBlank(scope)){ this.scope = scope; } } @Override public Class<?> getBeanClass() { return this.beanClass; } @Override public String getScope() { return this.scope; } @Override public boolean isSingleton() { return BeanDefinition.SCOPE_SINGLETON.equals(this.scope); } @Override public boolean isPrototype() { return BeanDefinition.SCOPE_PROTOTYPE.equals(this.scope); } @Override public String getFactoryBeanName() { return factoryBeanName; } @Override public String getFactoryMethodName() { return factoryMethodName; } @Override public String getInitMethodName() { return this.initMethodName; } @Override public String getDestoryMethodName() { return this.destroyMethodName; } } 复制代码
A:Map 复制代码
A:直接设计为不能重名 复制代码
Map 复制代码
创建bean实例,进行初始化 复制代码
public class DefaultBeanFactory implements BeanFactory,BeanDefinitionRegistry, Closeable { //common-logging包和log4j-api包配合即可 private final Log logger = LogFactory.getLog(getClass()); //考虑并发情况,256个前不需要进行扩容 private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); private Map<String,Object> beanMap = new ConcurrentHashMap<>(256); @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception { //参数检查 Objects.requireNonNull(beanName,"注册bean需要输入beanName"); Objects.requireNonNull(beanDefinition,"注册bean需要输入beanDefinition"); //检验给入的bean是否合法 if (!beanDefinition.validate()){ throw new Exception("名字为["+beanName+"]的bean定义不合法,"+beanDefinition); } if (this.containsBeanDefinition(beanName)){ throw new Exception("名字为["+beanName+"]的bean定义已经存在,"+this.getBeanDefinition(beanName)); } this.beanDefinitionMap.put(beanName,beanDefinition); } @Override public BeanDefinition getBeanDefinition(String beanName) { return this.beanDefinitionMap.get(beanName); } @Override public Boolean containsBeanDefinition(String beanName) { return this.beanDefinitionMap.containsKey(beanName); } @Override public Object getBean(String name) throws Exception { return this.doGetBean(name); } //不需要判断scope,因为只有单例bean才需要放入map中 //使用protected保证只有DefaultBeanFactory的子类可以调用该方法 protected Object doGetBean(String beanName) throws Exception{ Objects.requireNonNull(beanName,"beanName不能为空"); Object instance = beanMap.get(beanName); if (instance != null){ return instance; } BeanDefinition beanDefinition = this.getBeanDefinition(beanName); Objects.requireNonNull(beanDefinition,"beanDefinition不能为空"); Class<?> type = beanDefinition.getBeanClass(); //因为总共就只有3种方式,也不需要扩充或者是修改代码了,所以就不需要考虑使用策略模式了 if (type != null){ if (StringUtils.isBlank(beanDefinition.getFactoryMethodName())){ instance = this.createInstanceByConstructor(beanDefinition); } else { instance = this.createInstanceByStaticFactoryMethod(beanDefinition); } }else { instance = this.createInstanceByFactoryBean(beanDefinition); } this.doInit(beanDefinition,instance); if (beanDefinition.isSingleton()){ beanMap.put(beanName,instance); } return instance; } //构造方法来创建对象 private Object createInstanceByConstructor(BeanDefinition beanDefinition) throws IllegalAccessException, InstantiationException { try{ return beanDefinition.getBeanClass().newInstance(); } catch (SecurityException e){ logger.error("创建bean的实例异常,beanDefinition"+beanDefinition,e); throw e; } } //静态工厂方法(暂时不考虑带参数) private Object createInstanceByStaticFactoryMethod(BeanDefinition beanDefinition) throws Exception{ Class<?> type = beanDefinition.getBeanClass(); Method method = type.getMethod(beanDefinition.getFactoryMethodName(),null); return method.invoke(type,null); } //工厂bean方法来创建对象(暂时不考虑带参数) private Object createInstanceByFactoryBean(BeanDefinition beanDefinition) throws Exception{ Object factoryBean = this.doGetBean(beanDefinition.getFactoryBeanName()); Method method = factoryBean.getClass().getMethod(beanDefinition.getFactoryMethodName(),null); return method.invoke(factoryBean,null); } //初始化方法 private void doInit(BeanDefinition beanDefinition, Object instance) throws Exception{ if (StringUtils.isNotBlank(beanDefinition.getInitMethodName())){ Method method = instance.getClass().getMethod(beanDefinition.getInitMethodName(),null); method.invoke(instance,null); } } @Override public void close() throws IOException { //执行单例实例的销毁方法 //遍历map把bean都取出来然后调用每个bean的销毁方法 for (Map.Entry<String,BeanDefinition> entry : this.beanDefinitionMap.entrySet()){ String beanName = entry.getKey(); BeanDefinition beanDefinition = entry.getValue(); if (beanDefinition.isSingleton() && StringUtils.isNotBlank(beanDefinition.getDestoryMethodName())){ Object instance = this.beanMap.get(beanName); try { Method method = instance.getClass().getMethod(beanDefinition.getDestoryMethodName(),null); method.invoke(instance,null); }catch (NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e){ logger.error("执行bean["+beanName+"] "+beanDefinition+"的销毁方法异常",e); } } } } } 复制代码
A:可以提前实例化,空间换时间的方法,启动慢使用快并线程安全 复制代码
public class PreBuildBeanFactory extends DefaultBeanFactory{ private Log logger = LogFactory.getLog(getClass()); private List<String> beanNames = new ArrayList<>(); @Override public void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws Exception{ super.registerBeanDefinition(beanName,beanDefinition); synchronized (beanNames){ beanNames.add(beanName); } } //使用synchronized解决线程安全问题 public void preInstantiateSingletons() throws Exception{ synchronized (beanNames){ for (String name : beanNames){ BeanDefinition beanDefinition = this.getBeanDefinition(name); if (beanDefinition.isSingleton()){ this.doGetBean(name); if (logger.isDebugEnabled()){ logger.debug("preInstantiate:name="+name+" "+beanDefinition); } } } } } } 复制代码
public class Bean1 { public void doSomething(){ System.out.println(System.currentTimeMillis()+" "+this); } public void init(){ System.out.println("bean1的init已执行"); } public void destroy(){ System.out.println("bean1的destroy已执行"); } } 复制代码
Bean1Factory.java
public class Bean1Factory { public static Bean1 getBean1(){ return new Bean1(); } public Bean1 getOtherBean1(){ return new Bean1(); } } 复制代码
测试用例DefaultBeanFactoryTest
public class DefaultBeanFactoryTest { static DefaultBeanFactory defaultBeanFactory = new DefaultBeanFactory(); @Test public void testRegist() throws Exception{ GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition(); generalBeanDefinition.setBeanClass(Bean1.class); generalBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); generalBeanDefinition.setInitMethodName("init"); generalBeanDefinition.setDestroyMethodName("destroy"); defaultBeanFactory.registerBeanDefinition("bean1",generalBeanDefinition); } @Test public void testRegistStaticFactoryMethod() throws Exception{ GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition(); generalBeanDefinition.setBeanClass(Bean1Factory.class); generalBeanDefinition.setFactoryMethodName("getBean1"); defaultBeanFactory.registerBeanDefinition("staticBean1",generalBeanDefinition); } @Test public void testRegistFactoryMethod() throws Exception{ GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition(); generalBeanDefinition.setBeanClass(Bean1Factory.class); String factoryBeanName = "factory"; defaultBeanFactory.registerBeanDefinition(factoryBeanName,generalBeanDefinition); generalBeanDefinition = new GeneralBeanDefinition(); generalBeanDefinition.setFactoryBeanName(factoryBeanName); generalBeanDefinition.setFactoryMethodName("getOtherBean1"); generalBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE); defaultBeanFactory.registerBeanDefinition("factoryBean",generalBeanDefinition); } @AfterClass public static void testGetBean() throws Exception{ System.out.println("构造方法方式···"); for (int i = 0;i<3;i++){ Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("bean1"); bean1.doSomething(); } System.out.println("静态工厂方法方式···"); for (int i = 0;i<3;i++){ Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("staticBean1"); bean1.doSomething(); } System.out.println("工厂方法方式···"); for (int i = 0;i<3;i++){ Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("factoryBean"); bean1.doSomething(); } defaultBeanFactory.close(); } } 复制代码
构造方法方式··· bean1的init已执行 1555370012087 MySpring.Bean1@5e8c92f4 1555370012088 MySpring.Bean1@5e8c92f4 1555370012088 MySpring.Bean1@5e8c92f4 静态工厂方法方式··· 1555370012088 MySpring.Bean1@50134894 1555370012088 MySpring.Bean1@50134894 1555370012088 MySpring.Bean1@50134894 工厂方法方式··· 1555370012089 MySpring.Bean1@2957fcb0 1555370012089 MySpring.Bean1@1376c05c 1555370012090 MySpring.Bean1@51521cc1 bean1的destroy已执行复制代码