Spring框架基础(二)IOC容器和DI

        在Spring框架基础(一)中,我们知道传统MVC开发模式存在的缺点:对象的创建(时间及数量),对象之间的依赖,大量重复代码问题。并提出Spring以次解决这些问题的概念:IOC,DI,AOP。而实现这些概念,需要引入Spring的核心配置文件applicationContext.xml(也叫bean.xml),也就是说我们通过在核心配置文件中配置的方式,解决上述提出的问题。不过现在通常使用注解的方式,我们后面再介绍。

一、核心配置文件详解

从上一篇中,我们知道可以在Spring的核心配置文件中配置我们需要的对象,如下

<bean id="strudent" class="com.zc.a_hello.Strudent"></bean>

然后从容器中直接获取该对象,如下

// 得到IOC容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/zc/a_hello/applicationContext.xml");

// 从容器中获取bean
Strudent s = (Strudent) ac.getBean("strudent");

至此,我们解决了对象创建的问题:把对象的创建交给外部容器,那么如何解决对象的创建时间以及数量呢?

同样在配置文件中进行配置即可,如下

<bean id="strudent" class="com.zc.a_hello.Strudent" scope="singleton"></bean>

我们在配置的时候添加属性scope,默认值为singleton,即默认创建对象时是单例的(适用于Dao,Service),而且容器启动的时候就会创建对象

如果将scope设置为prototype,即设置对象为多例的(适用于Action),而且当调用对象时再创建对象

也就是说,我们通过配置Scope属性即可解决了对象的创建时间以及数量问题

如果我们设置对象为单例(容器启动时就应该创建对象),但是现在我们想要用到对象时再创建对象,那么我们可以再添加一个是否延迟加载的属性,如下

<bean id="strudent" class="com.zc.a_hello.Strudent" scope="singleton" lazy-init="false"></bean>

lazy-init="true" 时,用到对象再创建

lazy-init="false"(默认)时,容器启动就创建

属性lazy-init只对单例有效,如果我们对象时多例的,则该属性的设置无效

到目前为止,我们通过配置文件方式解决了对象创建,创建时间,创建数量的问题,我们回过头来再看一下对象创建,上面只介绍了一种调用无参构造函数的方式来创建对象,如下

<bean id="strudent" class="com.zc.a_hello.Strudent"></bean>

此外,还有带参数构造器创建对象,工厂类创建对象。分别如下

<!-- 带参数构造器     按实体类属性的顺序进行配置   属性类型为基本类型直接写,引用类型要加包名-->
<bean id="strudent" class="com.zc.b_create_obj.Strudent">
		<constructor-arg index="0" type="int" value="27"></constructor-arg>
		<constructor-arg index="1" type="java.lang.String" value="zc"></constructor-arg>
</bean>

这里假设Strudent类有两个属性,一个int age,一个String name,并提供有参构造函数。

工厂类创建对象又分为非静态方法创建对象和静态方法创建对象

<!-- 工厂类,非静态方法 -->
<!-- 先创建工厂 -->
<bean id="factory" class="com.zc.b_create_obj.ObjectFactory"></bean>
<!-- 在创建Strudent对象,用factory方的实例方法 -->
<bean id="strudent" factory-bean="factory" factory-method="getInstance"></bean>
	
	
<!-- # 工厂类: 静态方法 -->
<!-- 
	class 指定的就是工厂类型
	factory-method  工厂里的静态方法
-->
<bean id="strudent" class="com.zc.b_create_obj.ObjectFactory" factory-method="getStaticInstance"></bean>

 


接下来我们介绍如何解决对象之间的依赖关系,即如何给对象的属性赋值,常用方法如下

1)通过构造函数

	<bean id="strudent" class="com.zc.c_property.Strudent" scope="prototype">
		<constructor-arg value="27"></constructor-arg>
		<constructor-arg value="zc"></constructor-arg>
	</bean>

2) 通过set方法给属性注入值

     <bean id="strudent" class="com.zc.c_property.Strudent" scope="prototype">
		<property name="age" value="27"></property>
		<property name="name" value="zc"></property>
	</bean>

3) p名称空间,这里需要在配置文件里引入P名称空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
		
	
	<!-- 传统的注入: 
	 <bean id="strudent" class="com.zc.c_property.Strudent" >
	 	<property name="name" value="zc"></property>
	 </bean>
	-->
	<!-- p名称空间优化后 -->
	<bean id="strudent" class="com.zc.c_property.Strudent" p:name="zc"></bean>
	 
</beans>      

4) 注解

使用注解步骤:
    1)先引入context名称空间
        xmlns:context="http://www.springframework.org/schema/context"
    2)开启注解扫描,在核心配置文件: applicationContext.xml 中配置
        <context:component-scan base-package="com.zc.e_anno2"></context:component-scan>
    3)使用注解
        通过注解的方式,把对象加入ioc容器,然后同样通过注解进行注入

@Controller  // 控制层的组件
public class StrudentAction {

	@Resource(name = "strudentService")  // 根据名称查找
	private UserService strudentService;

	public String execute() {
		strudentService.save();
		return null;
	}
}
创建对象以及处理对象依赖关系,相关的注解:
@Component   指定把一个对象加入IOC容器

@Repository   作用同@Component; 在持久层使用
@Service      作用同@Component; 在业务逻辑层使用
@Controller    作用同@Component; 在控制层使用 

@Resource     属性注入

总结

本篇文章主要介绍了IOC容器是如何解决对象创建(4种不同创建方式),创建时间(容器启动时创建,需要时创建)及数量(单例,多例)的问题

同时介绍了如何解决对象直接依赖关系(DI)的,使用频率:注解>set()>P名称空间

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值