IOC控制反转:
把对象的创建交给spring容器来做
spring容器创建对象的方式
1、默认是调用默认的构造函数
2、利用静态工厂方法创建
spring调用工厂方法产生对象,但是真正创建对象还是由程序员来完成的
3、实例工厂方法
说明:
spring配置文件中,只要是一个bean就会为该bean创建对象
spring容器创建对象的时机
在单例的情况下
1、在默认的情况下,启动spring容器创建对象
2、在spring的配置文件bean中有一个属性lazy-init="default/true/false"
1、如果lazy-init为"default/false"在启动spring容器时创建对象
2、如果lazy-init为"true",在context.getBean时才要创建对象
意义:
在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,
如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了
内存中,如果有数据,则对内存来是一个消耗
在第二种情况下,可以减少内存的消耗,但是不容易发现错误
在多例的情况下
就是一种情况:在context.getBean时才创建对象
spring的bean中的scope
1、由spring产生的bean默认是单例的
2、可以在spring的配置文件中,scope的值进行修改="singleton/prototype/request/session/globalsession"
3、如果spring的配置文件的scope为"prototype",则在得到该bean时才创建对象
public class HelloWorld {
public HelloWorld(){
System.out.println("new instance");
}
public void hello(){
System.out.println("hello");
}
}
applicationContext.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
beans
把一个类放入到spring容器中,该类就是一个bean
-->
<!--
id 唯一标示符
class表示类的全名
-->
<bean id="helloWorld" class="cn.itcast.spring.sh.ioc.createobject.HelloWorld"></bean>
</beans>
这样就把HelloWorld对象的创建交给spring容器了来做,这就是IOC控制反转(把创建对象交给spring容器)
spring容器对象的生命周期:
1、spring容器创建对象
2、执行init方法
3、调用自己的方法
4、当spring容器关闭的时候执行destroy方法
spring的DI:依赖注入
依赖注入总是和控制反转同时出现,因为在创建对象的时候要给类中的属性赋值,总的一句话DI就是给属性赋值
public class Person {
private Long pid;
private String pname;
private Student student;
private Set sets;
public Person(String pname,Student student){
this.pname = pname;
this.student = student;
}
public Person(Long pid,String pname,Student student){
this.pid = pid;
this.pname = pname;
this.student = student;
}
public Person(){}
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Set getSets() {
return sets;
}
public void setSets(Set sets) {
this.sets = sets;
}
public List getLists() {
return lists;
}
public void setLists(List lists) {
this.lists = lists;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
private List lists;
private Map map;
private Properties properties;
}
我们可以看到这个Person类不是一个简单额POJO里面有引用类型Student、集合Set、Map、还有Properties这都不是简单类型,所有用spring的IOC创建对象的时候也要给里面的属性赋值
springDI的说明:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
-->
<bean id="person_Con" class="cn.itcast.spring.sh.di.constructor.Person">
<constructor-arg index="0" type="java.lang.Long" value="1"></constructor-arg>
<constructor-arg index="1" value="aaa"></constructor-arg>
<constructor-arg index="2" ref="student_Con"></constructor-arg>
</bean>
<bean id="student_Con" class="cn.itcast.spring.sh.di.constructor.Student"></bean>
</beans>
1、如果spring的配置文件中的bean中没有<constructor-arg>该元素,则调用默认的构造函数,如果自己写了个构造方法,必须要再写个默认的否则报错。
2、如果spring的配置文件中的bean中有<constructor-arg>该元素,则该元素确定唯一的构造函数
index 代表参数的位置 从0开始计算
type 指的是参数的类型
value 给基本类型赋值
ref 给引用类型赋值
如上面例子中的
springIOC和DI的意义:
实现了完全的面向接口编程