一、IOC(控制反转)
Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。
1.spring容器创建对象的方式
1)默认是调用默认的构造函数
<bean id=“personService" class="cn.itcast.bean.impl.PersonServiceImpl"/>
2)利用静态工厂方法创建
<bean id="personService" class="com.itcast.factory.PersonServiceFactory" factory-method="createPersonService" /> public class PersonServiceFactory { public static PersonService createPersonService(){ return new PersonServiceImpl(); } }
3)实例工厂方法:比较少用,有些开源项目会用。
说明:spring配置文件中,只要是一个bean就会为该bean创建对象
2.spring容器创建对象的时机
在单例的情况下:
1)在默认的情况下,启动spring容器创建对象
2)在spring的配置文件bean中有一个属性lazy-init="default/true/false":
如果lazy-init为"default/false"在启动spring容器时创建对象;
如果lazy-init为"true",在context.getBean时才要创建对象。
意义:
在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗。
在第二种情况下,可以减少内存的消耗,但是不容易发现错误。
在多例的情况下:
就是一种情况:在context.getBean时才创建对象
3.spring的bean中的scope
1)由spring产生的bean默认是单例的;
2)可以在spring的配置文件中,scope的值进行修改="singleton/prototype/request/session/global session"
3)如果spring的配置文件的scope为"prototype",则在得到该bean时才创建对象
4.spring容器对象的生命周期:
1)spring容器创建对象
2)执行init方法
3)调用自己的方法
4)当spring容器关闭的时候执行destroy方法
二、Spring的DI:依赖注入
1.如果spring的配置文件中的bean中没有<constructor-arg>该元素,则调用默认的构造函数
2.如果spring的配置文件中的bean中有<constructor-arg>该元素,则该元素确定唯一的构造函数
index 代表参数的位置 从0开始计算
type 指的是参数的类型
value 给基本类型赋值
ref 给引用类型赋值
3.使用属性setting方法进行注入
<bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl"> <!-- 基本类型,string类型 --> <property name="age" value="20"></property> <property name="name" value="张无忌"></property> </bean> <bean id="person" class="com.itcast.bean.Person" /> <bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl"> <property name="person" ref="person" /> </bean>
三、注解
1.注解就是为了说明java中的某一个部分的作用(Type)
2.注解都可以用于哪个部门是@Target注解起的作用
3.注解可以标注在ElementType枚举类所指定的位置上
4.
@Documented //该注解是否出现在帮助文档中
@Retention(RetentionPolicy.RUNTIME) //该注解在java,class和运行时都起作用
@Target(ElementType.ANNOTATION_TYPE)//该注解只能用于注解上
public @interface Target {
ElementType[] value();
}
5.用来解析注解的类成为注解解析器
四、@Resource注解的使用规则:
1.在spring的配置文件中导入命名空间:
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
2.引入注解解析器
<context:annotation-config></context:annotation-config>
3.在spring的配置文件中把bean引入进来
4.在一个类的属性上加
@Resource(name="student_annotation")
private Student student;
从该注解本身
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
}
1)该注解可以用于属性上或者方法上,但是一般用于属性上
2)该注解有一个属性name,默认值为""
5.分析整个过程:
1)当启动spring容器的时候,spring容器加载了配置文件;
2)在spring配置文件中,只要遇到bean的配置,就会为该bean创建对象
3)在纳入spring容器的范围内查找所有的bean,看哪些bean的属性或者方法上加有@Resource
4)找到@Resource注解以后,判断该注解name的属性是否为""(name没有写)
如果没有写name属性,则会让属性的名称的值和spring中ID的值做匹配,如果匹配成功则赋值;如果匹配不成功,则会按照类型进行匹配,如果匹配不成功,则报错;
如果有name属性,则会按照name属性的值和spring的bean中ID进行匹配,匹配成功,则赋值,不成功则报错
五、类扫描的注解
1.在spring的配置文件中导入命名空间
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
2.<context:component-scan base-package="cn.itcast.annotation.scan"></context:component-scan>
1)该注解解析器包含了两个功能:依赖注入和类扫描
2)在base-package包及子包下查找所有的类
3.如果一个类上加了@Component注解,就会进行如下的法则
如果其value属性的值为""
@Component
public class Person {}
==
<bean id="person" class="..Person">
如果其value属性的值不为""
@Component("p")
public class Person {}
==
<bean id="p" class="..Person">
4.按照@Resource的法则再次进行操作
六、xml与注解
1.xml书写麻烦,但是效率高
2.注解书写简单,但是效率低
七、注解:
依赖注入
1.@Resource
2.@Autowired
3.@Qualifier
类扫描
1.@Component
2.@Controller
3.@Repository
4.@Service