public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
SpellChecker.java
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
MainApp.java
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
public class TextEditor{
private SpellChecker spellChecker;
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
SpellChecker.java
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
Spring IOC(控制反转)
一、什么是IOC
控制反转
)又叫做DI(依赖注入
),它描述了对象的定义和依赖的一个过程,也就是说,依赖的对象通过构造参数、工厂方法参数或属性注入,当对象实例后依赖的对象才被创建,当创建bean后容器注入这些依赖对象。与原来在类中使用其他类时相比(new Object()),这个过程是反向
的,即对象与对象间的依赖不再是主动的去new 一个对象,而是交由Bean容器在对象实例化的时候进行注入。二、为什么要用IOC?
a. 原始的对象间的关系:
b.基于IOC容器的对象间的关系:
三、IOC的实现原理:
反射
,JAVA反射机制就是在运行状态
中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为JAVA语言的反射机制
;这里简单讲述一下为什么要使用反射:
无反射技术的工厂模式:
基于反射技术的工厂模式:
反射机制的作用:
反射技术的优缺点:
四、Spring IOC的重要内容
4.1 依赖注入的实现(DI)
构造函数
的注入TextEditor.java
SpellChecker.java
MainApp.java
xml配置文件
setter方法
的注入(由于注入是基于java反射机制
实现的,即使没有 setter 声明的方法,也可以进行注入)TextEditor.java
SpellChecker.java
xml配置文件
XML
的注入配置(如上面的配置)注解
的注入配置(通过@Autowired
进行注入)4.2 Spring IOC的初始化(Bean的初始化)
参考:https://www.jianshu.com/p/70886997c46b
主要分为三个步骤(容器的初始化是通过
refresh()
实现)Resource
定位BeanDefinition
,BeanDefinition定义了Bean的元信息、依赖关系等,即寻找Bean的过程。BeanDefinition
的信息已经定位到了,第二步就是把定义的BeanDefinition
在Ioc容器
中转化成一个Spring内部标示的数据结构的过程。注册
到IoC容器中,IoC容器是通过ConcurrentHashMap
来维护BeanDefinition信息的,key为beanName,value为BeanDefinition。五、IOC的优缺点
优点:
解耦
,基于单例模式可以有效减少系统资源的消耗。缺点:
反射
实现,性能会稍微差一些,单例模式引入了线程安全问题。六、IOC的源码解析
BeanFactory和ApplicationContext的区别
继承
自BeanFactory接口,同时继承了MessageSource和ResourceLoader等其他接口,相比BeanFactory,ApplicationContext提供了更多的扩展功能
,如能够实现国际化访问、事务传播及AOP等服务。懒加载
(延迟加载),BeanFactory加载后,需要第一次调用getBean()
方法才会实例化,而ApplicaitonContext实现的是饿汉加载
,在容器初始化的时候,会实例化所有的bean。及时检查
Bean是否完成注入,BeanFactory需要调用getBean()的时候才会抛出异常。参考