叩丁狼java学习第十三天-SpringBean

发布于 2021-03-24  1679 次阅读


1.初识Spring、IOC、DI

IOC:

Inversion of Control(控制反转):读作“反转控制”,更好理解,不是什么技术,而是一种设计
思想,好比于 MVC。
就是将原本在程序中手动创建对象的控制权,交由 IoC 容器来管理。

DI:

依赖注入
IoC 从字面意思上很难体现出谁来维护对象之间的关系,Martin Fowler 提出一个新的概念 DI,更明确
描述了”被注入对象(Service 对象)依赖 IoC 容器来配置依赖对象”。
所以两者配合在一起时:
IoC:指将对象的创建权,反转给了IoC 容器;
DI:指 IoC 容器创建对象的过程中,将对象依赖属性(常量,对象)通过配置设值给该对象。

2.SpringIOC管理bean的原理

@Test
public void testMockSpring() throws Exception {
   // 假设已从配置文件中解析到如下数据
   String className = "cn.wolfcode._01_hello.Person";
   String objName = "person";
   String propertyName = "name";
   String propertyValue = "C罗";
    // 反射获取字节码对象
   Class<?> clzz = Class.forName(className);
    // 反射创建对象,对应类必须存在公共无参的构造函数
   Object obj = clzz.newInstance();
   BeanInfo beanInfo = Introspector.getBeanInfo(clzz, Object.class);
   for(PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
   // 判断属性名与解析 XML 中属性是否一致
   if(pd.getName().equals(propertyName)) {
       // 若一致,调用对应 setter 方法设置
       pd.getWriteMethod().invoke(obj, propertyValue);
     }
   }
   // 把对象存容器 省略
   ((Person) obj).doWork();
}

3.getBean方法及Spring常见异常

1、按照名字

Person bean1 = (Person)ctx.getBean("person");


缺点:要强转,不太安全。
2、按照类型
要求在 Spring 中只配置一个这种类型的实例。缺点:可能找多个报错。

Person bean2 = ctx.getBean(Person.class);


3、按照名字和类型

Person bean3 = ctx.getBean("person3", Person.class);


4、常见异常


异常1:NoSuchBeanDefinitionException: No bean named 'person2' available
按照 bean 名称去获取 bean 时,不存在名称为 person2 的 bean。


异常2:NoUniqueBeanDefinitionException: No qualifying bean of type
'cn.wolfcode._01_hello.Person' available: expected single matching bean but found 2:
person,person2
按照 cn.wolfcode._01_hello.Person 类型去获取 bean 时,期望找到该类型唯一的一个 bean,可是此
时找到了两个。


异常3:BeanDefinitionParsingException: Configuration problem: Bean name 'person' is already
used in this element Offending resource: class path resource [01.hello.xml]
在 01.hello.xml 文件中,多个 bean 元素的名称是 person。

4.bean的创建时机

启动 Spring 容器的时候就会创建所有的 bean

5.bean的实例化方式

5.1构造器实例化

无参构造器,最标准,也使用最多

package cn.wolfcode._02_ioc;
   public class Cat1 {
   public Cat1() {
      System.out.println("Cat1 对象被创建了");
   }
}

<bean id="cat1" class="cn.wolfcode._02_ioc.Cat1"/>

5.2beanFactory实例化

package cn.wolfcode._02_ioc;
// 实列工厂类
public class Cat2FactoryBean implements FactoryBean<Cat2> {
   // 创建对象的方法,给 Spring 用, 创建对象的时候使用
   @Override
   public Cat2 getObject() throws Exception {
      Cat2 cat2 = new Cat2();
      return cat2;
   }
// 判断类型用的方法,给 Spring 用
@Override
public Class<?> getObjectType() {
      return Cat2.class;
   }
}
<bean id="cat2" class="cn.wolfcode._02_ioc.Cat2FactoryBean"/>

欢迎欢迎~热烈欢迎~