SSM——Spring(2)——SpringIoC 控制反转

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jinxlzc/article/details/88218001

自学笔记,如有错误请指出,我虚心改正

环境说明:Windows10、MyEclipse2016ci、jdk1.8、MySQL5.7、Tomcat9.0


目录

SpringIoC的基本概念

SpringIoC容器

BeanFactory

ApplicationContext

1、通过ClassPathXmlApplicationContext创建

2、通过FileSystemXmlApplicationContext创建

3、通过Web服务器实例化ApplicationContext容器

依赖注入的类型

使用构造方法注入

创建dao包

创建service包

编写配置文件

创建test包

使用属性的setter方法注入

创建DIServiceImlps

将DIServiceImpls类托管给Spring

在test中测试setter方法注入


SpringIoC的基本概念

上回提到了Spring IoC的工作机制,究竟何为IoC?如何理解IoC?IoC有何优势?

IoC即Inversion of Control “控制反转”是Spring的基础,简单的理解是把“创建对象的权利”交由Spring,仅用语言很难形容,我参考知乎用户Mingqi的回答来帮助理解,SSM——Spring(番外2)——IoC形象理解(转自知乎Mingqi的回答)(https://blog.csdn.net/jinxlzc/article/details/88526660


SpringIoC容器

Spring提供了两种类型的IoC容器的实现:

1、BeanFactory:IoC容器的基本实现,它是一个管理Bean 的工厂,主要负责初始化各种Bean

2、ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口

下面我分别用以上两种类型IoC容器实现一下


BeanFactory

在创建BeanFactory实例时需要提供XML文件的绝对路径,现在我就在上次做的SpringDemo1中修改实现,将Text.Text.java做如下修改

package Test;
import dao.TestDao;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
/**
 * @author lzc
 *
 */
public class Test {
	public static void main(String[] args) {
		BeanFactory beanfact=new XmlBeanFactory(new FileSystemResource("C:\\Users\\64522\\Workspaces\\MyEclipse 2016 CI\\SpringDome1\\src\\applicationContext.xml"));
		TestDao td=(TestDao)beanfact.getBean("test");
		td.say();
	}
}

然而,BeanFactory类已被最新的Spring废弃掉,证据就是下图

 所以另一种方式即ApplicationContext是现在最主流,也是我们最常用的方式


ApplicationContext

刚才提到,ApplicationContext是BeanFactory的子接口,ApplicationContext接口除了包含BeanFactory的所有功能外还提供了对国际化、资源访问、事件传播等内容的支持

创建ApplicationContext接口实例的通常一下有3种方法:


1、通过ClassPathXmlApplicationContext创建

即相对路径创建,将src下的xml使用通过ClassPathXmlApplicationContext进行指定,这种方法是最常用,也是之前Spring(1)中使用的方法,并且还是我人最喜欢的一种方法,具体实现在应用层的代码如下:

package Test;
import dao.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author lzc
 *
 */
public class Test {
	public static void main(String[] args) {
		ApplicationContext appCon =new ClassPathXmlApplicationContext("applicationContext.xml");
		TestDao thetest=(TestDao)appCon.getBean("test");
		thetest.say();
	}
}


2、通过FileSystemXmlApplicationContext创建

即相绝对路径创建,使用FileSystemXmlApplicationContext指定某一路径下 的xml配置文件,这里我把原项目中的xml右键属性复制绝对路径,不要忘了把"\"改为"\\",具体实现在应用层的代码如下:

package Test;
import dao.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
 * @author lzc
 *
 */
public class Test {
	public static void main(String[] args) {
		ApplicationContext appCon=new FileSystemXmlApplicationContext("C:\\Users\\64522\\Workspaces\\MyEclipse 2016 CI\\SpringDome1\\src\\applicationContext.xml");
		TestDao thetest=(TestDao)appCon.getBean("test");
		thetest.say();
	}
}

3、通过Web服务器实例化ApplicationContext容器

 在Web服务器实例化ApplicationContext容器时,一般基于org.springframework.web.context.ContextLoaderListener的方式实现,需要将spring-web-5.1.5.RELEASE.jar导入项目中,然后在项目的web.xml中配置如下代码,其中context-param标签中内容是为了加载src目录下classpath:applcationContext.xml文件,listener标签中内容是为了指定以ContextLoaderListener方式启动Spring容器

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:applcationContext.xml
    </param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

依赖注入的类型

在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象注入Bean组件中。Spring实现依赖注入的常用方式有两种,一种是使用构造方法注入,另一种是使用属性的setter方法注入


使用构造方法注入

Spring框架可以采用Java的反射机制,通过构造方法完成依赖注入。下面新建一个SpringDemo2项目实现构造方法注入的过程,SpringDemo2的结构与使用的包与SpringDemo1相同


创建dao包

在SpringDemo2项目中创建dao包,并在该包中创建DIDao接口和接口实现类DIDaoImpl,创建dao包的目的是在service中使用构造方法依赖注入DIDao接口对象

DIDao代码:

package dao;

/**
 * @author lzc
 *
 */
public interface DIDao {
	public void say();
}

 DIDaoImpl代码:

package dao;

/**
 * @author lzc
 *
 */
public class DIDaoImpl implements DIDao{
	@Override
	public void say() {
		System.out.println("DIDao say:Hello");
	}
}

创建service包

在SpringDemo2项目中创建service包,并在该包中创建DIService接口和接口的实现类DIServiceImpl,在DIServiceImpl中使用构造方法依赖注入DIDao接口对象

DIService代码:

package service;

/**
 * @author lzc
 *
 */
public interface DIService {
	public void say();
}

DIServiceImpl代码:

package service;
import dao.DIDao;
/**
 * @author lzc
 *
 */
public class DIServiceImpl implements DIService{
	private DIDao diDao;
	public DIServiceImpl(DIDao diDao)
	{
		super();
		this.diDao=diDao;
	}
	@Override
	public void say()
	{
		diDao.say();
		System.out.println("DIService构造方法注入say:Hello");
	}
}

编写配置文件

在src下创建Spring的配置文件applicationContext.xml,在配置文件中将dao.DIDaolmpl类托管给Spring,然后将service.DIServiceImpl类托管给Spring,让Spring创建其对象,同时给构造方法传递实参。

配置文件代码:

<?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.xsd">
   
    <bean id="myDIDao" class="dao.DIDaoImpl"/>
	<bean id="DIService" class="service.DIServiceImpl">
		<constructor-arg index="0" ref="myDIDao"/>
	</bean>
</beans>

第一个bean标签将制定类DIDaoImpl配置给Spring让Spring创建其实例

第二个bean标签使用构造方法注入,将myDIDao注入到DIServiceImpl类的属性diDao上

constructor-arg元素用于定义类构造方法的参数,index用于定义参数的位置,ref指定某个实例的引用如果参数是常量值,ref由value代替


创建test包

在项目中创建test包,并在包中创建测试类TestDI

TestDI代码如下:

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.DIService;

/**
 * @author lzc
 *
 */
public class TestDI {
	public static void main(String[] args) {
		ApplicationContext appCon=new ClassPathXmlApplicationContext("applicationContext.xml");
		DIService ds=(DIService)appCon.getBean("DIService");
		ds.say();
	}
}

运行结果如下:


使用属性的setter方法注入

setter方法注入是利用JavaBean规范所定义的setter方法来完成注入,对于setter方法注入,Spring框架也是使用Java 的反射机制实现的,现在将刚才的SpringDemo2中实现setter方法注入


创建DIServiceImlps

在service包下建用来测试setter方法注入的DIService接口实现类DIServiceImlps,在DIServiceImlps类中使用属性的setter方法依赖注入DIDao接口对象

DIServiceImlps代码如下:

package service;
import dao.DIDao;
/**
 * @author lzc
 *
 */
public class DIServiceImpls implements DIService{
	private DIDao diDao;
	public void setDiDao(DIDao diDao) {
		this.diDao = diDao;
	}
	@Override
	public void say()
	{
		diDao.say();
		System.out.println("DIService setter方法注入say:Hello");
	}
}

将DIServiceImpls类托管给Spring

将DIServiceImpls类托管给Spring,让Spring创建其对象,同时调用DIServiceImpls类的setter方法完成依赖注入

在配置文件中添加如下代码:

<bean id="DIServices" class="service.DIServiceImpls">
		<property name="diDao" ref="myDIDao"/>
</bean>

调用DIServiceImpls类的setter方法,将myDIDao注入到DIServiceImpls类的属性diDao上


在test中测试setter方法注入

在测试类的主方法中通过容器获取DIServices实例,测试setter方法注入

在测试类添加如下代码

DIService dss=(DIService)appCon.getBean("DIServices");
dss.say();

运行结果如下:


项目的完整结构如下: 

猜你喜欢

转载自blog.csdn.net/jinxlzc/article/details/88218001