控制反转(IOC--Inversion of control)
所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转
Spring的控制反转:
把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。
步骤:
A. 启动spring容器
1、在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(" xxx.xml");
可以在整个类路径中寻找xml文件
* 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
* classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。
例如:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
2、在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。
注:经常用第一种方法启动容器
B. 从spring容器中提取对象
别名
通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。

创建对象三种的方式
无参构造函数
无参构造函数
<bean id="helloWorld" class="com.hw.entity.HelloWorldFactory" >
</bean>

静态工厂
public class HelloWorld {
public void hello() {
System.out.println("哈哈");
}
}
--------------------------------------------
public class HelloWorldFactory {
public static HelloWorld getFactory() {
return new HelloWorld();
}
}
---------------------------------------------------
<bean id="helloWorld2" class="com.hw.entity.HelloWorldFactory" factory-method="getFactory"></bean>
@Test
public void test001() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld hello = (HelloWorld) ac.getBean("helloWorld2");
hello.hello();
}
}

实例工厂
public class HelloWorld {
public void hello() {
System.out.println("哈哈");
}
}
public class HelloWorldFactory {
public HelloWorld getFactory() {
return new HelloWorld();
}
}
<bean id="helloWorld" class="com.hw.entity.HelloWorldFactory" ></bean>
<bean id="helloWorld3" factory-bean="helloWorld" factory-method="getFactory"></bean>
@Test
public void test001() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld hello = (HelloWorld) ac.getBean("helloWorld2");
hello.hello();
}
}

Bean的作用域 ,对象的scope
五种:
1.singleton:单例模式
singleton(默认值)
在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初
始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<bean id="xxx" class="com.xxx.xxx" lazy-init="true"/>
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,

2.prototype:原型模式
允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的
整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的
昂贵资源都是客户端的责任。

3.request
4.session
5.global session
初始化bean时机
Spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一
部分,ApplicationContext会自动创建并配置所有的singleton bean.通常情况下这是件好事。
因为这样在配置中有任何错误能立即发现。
Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
Lazy-init 为true,spring容器将在调用该类的时候出错。
如果scope为prototype, Lazy-init将失去作用
init、destroy
Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean
的两个生命周期方法。
public class HelloWorld {
public HelloWorld() {
System.out.println("new instance");
}
public void init() {
System.out.println("init");
}
public void destroy() {
System.out.println("detroy");
}
public void hello() {
System.out.println("哈哈");
}
}
-----------------------------------------------
<bean id="helloWorld" class="com.hw.entity.HelloWorld"
init-method="init" destroy-method="destroy" scope="prototype">
</bean>
---------------------------------------------------------
@Test
public void test001() {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
helloWorld.hello();
ClassPathXmlApplicationContext applicationContext =
(ClassPathXmlApplicationContext)context;
applicationContext.close();
}
