一. IOC(控制反转)
Spring容器创建对象的三种方式:
1.利用默认的构造方法:
在 src 目录下新建 applicationContext.xml 文件,这是 spring 配置文件。
<bean id="helloIoc" class="com.ys.ioc.HelloIoc" ></bean>
<!-- 别名属性 name:和bean的 id 属性对应 -->
<alias name="helloIoc" alias="helloIoc2"/>
测试代码:
public void testCreateObjectByConstrutor(){
//1、启动 spring 容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2、从 spring 容器中取出数据
HelloIoc IOC = (HelloIoc) context.getBean("helloIoc");
//3、通过对象调用方法
IOC.sayHello();
//利用配置文件 alias 别名属性创建对象
HelloIoc IOC2 = (HelloIoc) context.getBean("helloIoc2");
IOC2.sayHello();
}
2.利用静态工厂方法:
首先创建静态工厂类 HelloStaticFactory.java
接着在 applicationContext.xml 中进行如下配置:
测试类:
public void createObjectStaticFactory(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloIoc staticFactory = (HelloIoc) context.getBean("helloStaticFactory");
staticFactory.sayHello();
}
spring容器只负责调用静态工厂方法,而这个静态工厂方法内部实现由程序员完成
3. 利用实例工厂方法:
首先创建实例工厂类 HelloInstanceFactory .java
public class HelloInstanceFactory {
public HelloInstanceFactory(){
System.out.println("实例工厂方法构造函数");
} //利用实例工厂方法创建对象
public HelloIoc getInstance(){
HelloIoc instanceIoc = new HelloIoc();
return instanceIoc;
}}
接着在 applicationContext.xml 中进行如下配置:
<!-- 创建对象的第三种方式:利用实例工厂方法
factory-bean:指定当前Spring中包含工厂方法的beanID
factory-method:工厂方法名称 -->
<bean id="instanceFactory" class="com.ys.ioc.HelloInstanceFactory"></bean>
<bean id="instance" factory-bean="instanceFactory" factory-method="getInstance"></bean>
测试类:
public void createObjectInstanceFactory(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloIoc staticFactory = (HelloIoc) context.getBean("instance"); staticFactory.sayHello();
}
Spring容器的声明周期:
1、spring容器创建对象
2、执行init方法
3、调用自己的方法
4、当spring容器关闭的时候执行destroy方法
bean中的scope:
1.默认scope的值是singleton,即产生的对象是单例的
<bean id="helloIoc" scope="singleton" class="com.ys.ioc.HelloIoc" ></bean>
2.scope=“prototype”
多例模式,并且spring容器启动的时候并不会创建对象,而是在得到 bean 的时候才会创建对象
applicationContext.xml 文件中配置:
<bean id="helloIoc" scope="prototype" class="com.ys.ioc.HelloIoc" ></bean>
在单例模式下,启动 spring 容器,便会创建对象;在多例模式下,启动容器并不会创建对象,获得 bean 的时候才会创建对象
Spring创建bean的时机:
1.默认情况下,启动 spring 容器便创建对象(遇到bean便创建对象)
2.在spring的配置文件bean中有一个属性 lazy-init=“default/true/false”,如果lazy-init为"true",在context.getBean时才要创建对象。
<bean id="helloIoc" lazy-init="true" class="com.ys.ioc.HelloIoc" ></bean>
在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗。
反过来,在第二种情况下,可以减少内存的消耗,但是不容易发现错误.
二. DI(依赖注入)
spring动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
1.利用set给属性赋值:
2.利用构造函数给属性赋值:
<!-- 根据构造函数赋值 -->
<!-- index 代表参数的位置 从0开始计算
type 指的是参数的类型,在有多个构造函数时,可以用type来区分,要是能确定是那个构造函数,可以不用写type
value 给基本类型赋值
ref 给引用类型赋值 -->
<bean id="person_con" class="com.ys.di.Person">
<constructor-arg index="0" type="java.lang.Long" value="1">
</constructor-arg>
<constructor-arg index="1" type="com.ys.di.Student" ref="student_con"></constructor-arg> </bean>
<bean id="student_con" class="com.ys.di.Student"></bean>
1、如果spring的配置文件中的bean中没有该元素,则调用默认的构造函数
2、如果spring的配置文件中的bean中有该元素,则该元素确定唯一的构造函数
三. 注解
1. 过程
- 在 applicationContext.xml 中引入命名空间
- 在 applicationContext.xml 文件中引入注解扫描器
- 在 Person 类中添加注解@Component
@Component
public class Person{}
等价于
<bean id = "person" class = "...Person">
@Component(“p”)
public class Person {}
等价于
<bean id="p" class="..Person">
2.注解
下面三个注解是 @Component 注解的衍生注解,功能一样
@Repository :dao层
@Service:service层
@Controller:web层
3.Resourse注解
@Resource 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Resource 的使用来消除 set ,get方法。
@Resource注解以后,判断该注解name的属性是否为""(name没有写)
①、如果没有写name属性,则会让属性的名称的值和spring配置文件bean中ID的值做匹配(如果没有进行配置,也和注解@Component进行匹配),如果匹配成功则赋值,如果匹配不成功,则会按照spring配置文件class类型进行匹配,如果匹配不成功,则报错。
②、如果有name属性,则会按照name属性的值和spring的bean中ID进行匹配,匹配成功,则赋值,不成功则报错。
4. @Autowired
功能和注解 @Resource 一样,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。只不过注解@Resource 是按照名称来进行装配,而@Autowired 则是按照类型来进行装配。